Как обойти запрет серверных вызовов при завершении работы в 1С:Предприятие 8.3?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей IT и автоматизация бизнеса
← На главную

Начиная с версии платформы 8.3.8 (при отключении режима совместимости или установке совместимости с версиями 8.3.8, 8.3.10 и выше), разработчики сталкиваются с критическим изменением: блокировкой синхронных серверных вызовов и интерактивных окон при завершении работы программы. Разберем причины этого нововведения платформы, рассмотрим примеры обхода и выделим рекомендованные архитектурные решения.

Причины изменения поведения платформы

Выясним причину, почему разработчики платформы пошли на такие ограничения. Главным фактором стала унификация работы тонкого клиента и веб-клиента. В веб-браузерах при закрытии вкладки или окна невозможно гарантировать выполнение синхронных сетевых запросов к серверу или отображение модальных диалогов.

В связи с этим платформа 1С блокирует любые серверные вызовы и модальные взаимодействия в следующих событиях:

  1. Обработчик модуля приложения ПередЗавершениемРаботыСистемы(Отказ, ТекстПредупреждения).
  2. Обработчик модуля приложения ПриЗавершенииРаботыСистемы().
  3. Событие формы ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка) при значении ЗавершениеРаботы = Истина.
  4. Событие формы ПриЗакрытии(ЗавершениеРаботы) при значении ЗавершениеРаботы = Истина.

Кроме того, изменилось поведение параметра Отказ = Истина: платформа больше не отменяет завершение работы немедленно и программно. Вместо этого пользователю показывается стандартный системный диалог с возможностью завершить работу или остаться в программе. Если пользователь подтверждает закрытие, сеанс завершается принудительно без шанса выполнить серверный код.

Вариант решения: отмена завершения через обработчик ожидания

Посмотрим на практический пример, предложенный разработчиками для ситуаций, когда при выходе необходимо выполнить служебные действия с открытыми формами или передать данные на сервер. Идея заключается в установке отказа от закрытия и немедленном подключении однократного обработчика ожидания.

Разберем по шагам реализацию в клиентском модуле:


Процедура ПередЗавершениемРаботыСистемы(Отказ, ТекстПредупреждения) Экспорт
    Если АСФСерверныеВызовыЗапрещены = Истина Тогда
        Возврат;
    КонецЕсли;
    
    // Блокируем текущую попытку завершения
    Отказ = Истина;
    
    // Подключаем однократный обработчик ожидания для выполнения действий вне контекста закрытия
    ПодключитьОбработчикОжидания("АСФПодключаемый_ПередЗавершениемРаботыСистемы", 0.1, Истина);
КонецПроцедуры

Теперь рассмотрим саму процедуру, вызываемую обработчиком ожидания. В ней система находится уже в обычном клиентском контексте, где разрешены серверные вызовы и манипуляции с интерфейсом:


Процедура АСФПодключаемый_ПередЗавершениемРаботыСистемы() Экспорт
    Отказ = Ложь;
    
    // Вызов стандартных механизмов БСП и оборудования
    СтандартныеПодсистемыКлиент.ПередЗавершениемРаботыСистемы(Отказ);
    МенеджерОборудованияКлиент.ПередЗавершениемРаботыСистемы();
    
    // Обход всех открытых окон и закрытие/обработка особых форм
    Окна = ПолучитьОкна();
    МассивОсобыхФорм = Новый Массив;
    МассивОсобыхФорм.Добавить("Обработка.ТекущиеДела.Форма.Форма");
    
    Для Каждого ТекущееОкно Из Окна Цикл
        Для Каждого ТекущаяФорма Из ТекущееОкно.Содержимое Цикл
            Если МассивОсобыхФорм.Найти(ТекущаяФорма.ИмяФормы) <> Неопределено Тогда
                Попытка
                    ТекущаяФорма.АСФВыполнитьПередЗакрытием();
                Исключение
                    // Обработка исключений при вызове методов формы
                КонецПопытки;
            Иначе
                ТекущаяФорма.Закрыть();
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
    // Взводим флаг для предотвращения повторной блокировки
    АСФСерверныеВызовыЗапрещены = Истина;
    
    // Повторно инициируем корректное завершение работы
    ЗавершитьРаботуСистемы(Ложь);
КонецПроцедуры

Важное замечание: данный подход позволяет обойти ограничение в тонком клиенте, однако в веб-клиенте при прямом закрытии вкладки браузера этот механизм работать не будет, так как браузер просто уничтожает поток JavaScript.

Рекомендованные архитектурные подходы

Проанализируем правильные с точки зрения архитектуры 1С способы работы с данными при завершении сеанса:

  1. Модель немедленного сохранения: не накапливайте критически важные данные на клиенте в расчете на сохранение перед выходом. Пользовательские настройки, параметры и состояния документов следует записывать на сервер в момент изменения данных или при штатных действиях пользователя.
  2. Перенос логики на серверные регламентные задания: задачи вроде фиксации времени выхода пользователя, освобождения внешних сессий или обмена данными должны контролироваться сервером (например, фоновыми заданиями по таймауту отсутствия активности), а не клиентским приложением при закрытии.
  3. Использование стандартных подсистем БСП: Библиотека Стандартных Подсистем полностью переведена на асинхронную модель работы. Используйте типовые механизмы подсистемы завершения работы пользователей, не переопределяя базовое поведение.

Диагностика и сопутствующие нюансы при переходе на новые режимы совместимости

Для предотвращения падений системы рекомендуется включить встроенный контроль конфигуратора. Для этого перейдите в меню: Сервис → Параметры → Запуск 1С:Предприятия и установите флаг проверки серверных вызовов в обработчиках событий.

Также обратите внимание на сопутствующие изменения платформы при переходе на режим совместимости 8.3.10. В запросах ужесточился контроль типов: запрещено объединять через ОБЪЕДИНИТЬ ВСЕ поля разных типов, если одно из них является строкой неограниченной длины. В отчетах на СКД при передаче строковых констант в параметры необходимо явно указывать ограничение длины строки (например, Строка(50)), иначе запросы будут завершаться с ошибкой.

← На главную