Как выводить сообщения пользователю в процессе выполнения длительной серверной процедуры в 1С?

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

При разработке в 1С мы часто сталкиваемся с необходимостью выполнить сложный и долгий алгоритм обработки данных на сервере. Это может быть закрытие месяца, массовое проведение документов или загрузка большого объема данных. Естественно, нам хочется информировать пользователя о том, что происходит внутри этой процедуры: на каком этапе находится процесс, сколько объектов обработано или какие возникли предупреждения. Давайте разберем по шагам, как правильно реализовать такой вывод сообщений в процессе выполнения длительной операции.

Почему стандартный вывод не работает в процессе?

Для начала проанализируем ситуацию, с которой сталкиваются многие программисты. Мы пытаемся вставить метод Сообщить() или использовать объект СообщениеПользователю внутри длинного серверного цикла. Однако вместо ожидаемого появления сообщений по мере выполнения кода, мы видим, что интерфейс «зависает», а все сообщения вываливаются на экран единым списком только после полного завершения процедуры.

Выясним причину этого явления. В архитектуре управляемого приложения 1С клиент и сервер общаются синхронно в рамках одного серверного вызова. Когда мы запускаем процедуру на сервере, клиент полностью блокируется и переходит в режим ожидания ответа. Любые вызванные в процессе функции платформы накапливают текстовые сообщения в специальном буфере на сервере. Эти данные передаются на клиент только в момент возврата управления (когда процедура полностью отработала). Именно поэтому единственный методологически правильный выход для отображения процесса в реальном времени — это использование асинхронности, то есть запуск процесса в отдельном потоке (фоновом задании).

Решение 1: Использование фоновых заданий через Библиотеку Стандартных Подсистем (БСП)

Рассмотрим самый правильный и рекомендуемый вариант для конфигураций, построенных на базе БСП (например, 1С:Управление торговлей 11.4). В БСП уже есть целый готовый «огород» — подсистема «Длительные операции», которая берет на себя всю рутину по управлению фоновыми потоками.

Разберем механику реализации по шагам:

  1. Запуск процедуры: Вместо прямого серверного вызова, на клиенте мы вызываем метод модуля ДлительныеОперацииКлиент, который инициирует серверный метод ДлительныеОперации.ВыполнитьВФоне().
  2. Ожидание и опрос: БСП автоматически запускает обработчик ожидания на клиенте с помощью процедуры ДлительныеОперацииКлиент.ОжидатьЗавершение(). Эта процедура с заданной периодичностью (например, каждые 2 секунды) делает короткие пинги на сервер, чтобы узнать состояние нашего задания.
  3. Передача прогресса: Внутри нашего тяжелого серверного кода мы периодически вызываем специальный метод ДлительныеОперации.СообщитьПрогресс(). В него мы передаем процент выполнения и текст текущей операции (например, «Обработан документ 10 из 100»).
  4. Отображение: При очередном такте опроса клиент получает эти данные и выводит пользователю красивое стандартизированное окно с прогресс-баром и поясняющим текстом.

Также, если вы работаете с чистой платформой без БСП, можно реализовать аналогичный механизм самостоятельно, используя метод ПолучитьСообщенияПользователю() для объекта фонового задания, вызывая его по таймеру на клиенте.

Решение 2: Использование Временного хранилища для передачи статусов

В качестве альтернативы встроенному прогрессу БСП или в самописных конфигурациях, мы посмотрим на пример использования временного хранилища. Это классический и очень надежный паттерн.

Проанализируем этот подход:

  1. Перед запуском фонового задания на сервере мы создаем уникальный адрес во временном хранилище.
  2. Передаем этот адрес в качестве параметра в наше фоновое задание.
  3. Фоновое задание в цикле (например, каждые 100 итераций) формирует структуру с текущим статусом: количество обработанных строк, тексты информационных сообщений. Эту структуру оно помещает по нашему адресу с помощью метода платформы.
  4. Клиентская форма подключает обработчик ожидания, который регулярно читает данные по этому адресу во временном хранилище.
  5. Полученные данные клиент выводит в элементы формы. Например, обновляет текст декорации или выводит всплывающие подсказки через метод Состояние().

Решение 3: Использование Системы взаимодействия (СВ)

Если в вашей базе активно используется Система взаимодействия (СВ), рассмотрим еще один современный метод. Система взаимодействия работает по принципу веб-сокетов, что обеспечивает постоянное двустороннее соединение между сервером СВ и клиентом.

Преимущество этого метода в том, что сообщения доставляются пользователю моментально и асинхронно, полностью минуя классический цикл «клиент-серверного вызова».

Посмотрим на пример того, как это работает:

Важный нюанс: Перехват ошибок в фоновых заданиях

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

Если ваш код внутри фонового задания упадет с необработанной ошибкой (исключением), фоновое задание просто завершится со статусом «Отменено» или «Ошибка». Проблема в том, что платформа «тихо» погасит этот процесс. Пользователь ничего не увидит, окно прогресса просто закроется, и возникнет иллюзия, что операция успешно завершилась (или просто исчезла).

Чтобы избежать этой проблемы, клиентский код, который опрашивает фоновое задание (или встроенный механизм БСП, если вы настраиваете его вручную), должен обязательно проверять статус задания при его завершении. Если статус сигнализирует об ошибке, необходимо получить свойство ИнформацияОбОшибке у объекта фонового задания и явно вывести текст этой ошибки на экран с помощью предупреждения. Только так мы обеспечим прозрачность процесса и понимание ситуации для конечного пользователя.

← На главную