К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как получить сообщения из фонового задания 1С

Как получить сообщения пользователю из фонового задания 1С: метод ПолучитьСообщенияПользователю, ДлительныеОперации БСП, регистры и протоколы. Примеры кода и типичные ошибки.

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

Основной механизм — метод менеджера фоновых заданий ФоновыеЗадания.ОжидатьЗавершенияВыполнения() (в новых версиях платформы; ранее — ОжидатьЗавершения), после которого у объекта фонового задания вызывается ПолучитьСообщенияПользователю(). В конфигурациях на БСП задачу решает модуль ДлительныеОперации, который сам возвращает сообщения вместе с результатом. Ниже разобраны оба подхода, а также альтернативы для длительных процессов, где сообщения нужны до завершения задания.

Почему сообщения фонового задания не видны пользователю

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

Из этого следуют два практических вывода. Во-первых, сообщения доступны только после завершения задания — «подсмотреть» их в середине выполнения штатными средствами объекта фонового задания нельзя. Во-вторых, если задание завершилось аварийно, сообщения всё равно можно получить, и в них часто содержится причина падения, что упрощает диагностику.

Базовый способ: ПолучитьСообщенияПользователю

Классический сценарий без БСП выглядит так: запускаем задание через ФоновыеЗадания.Выполнить(), дожидаемся завершения, затем читаем сообщения. Важно сохранить объект задания, возвращаемый методом Выполнить(), — именно через него выполняется ожидание и извлечение сообщений.

&НаКлиенте

Процедура ЗапуститьОбработку(Команда)

ПараметрыПроцедуры = Новый Массив;

ПараметрыПроцедуры.Добавить(ПериодОтчета);

Задание = ФоновыеЗадания.Выполнить(

"ОбработкаДанныхСервер.ВыполнитьЗагрузку",

ПараметрыПроцедуры,

,

"Загрузка данных");

Попытка

Задание.ОжидатьЗавершенияВыполнения(60);

Исключение

// истёк таймаут ожидания — задание ещё работает

КонецПопытки;

Если Задание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда

Сообщения = Задание.ПолучитьСообщенияПользователю(Истина);

Для Каждого Сообщение Из Сообщения Цикл

Сообщение.Сообщить();

КонецЦикла;

КонецЕсли;

КонецПроцедуры

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

Получение сообщений при аварийном завершении

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

Если Задание.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда

Сообщения = Задание.ПолучитьСообщенияПользователю(Истина);

Для Каждого Сообщение Из Сообщения Цикл

Сообщение.Сообщить();

КонецЦикла;

Если Задание.ИнформацияОбОшибке <> Неопределено Тогда

Сообщить("Ошибка фонового задания: "

+ Задание.ИнформацияОбОшибке.Описание);

КонецЕсли;

КонецЕсли;

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

Решение через БСП: ДлительныеОперации

В типовых конфигурациях на библиотеке стандартных подсистем ручная работа с фоновыми заданиями заменена программным интерфейсом ДлительныеОперации. Метод ДлительныеОперации.ВыполнитьВФоне() запускает процедуру общего модуля, а результат возвращается через оповещение в указанную клиентскую процедуру. Сообщения пользователю приходят в составе структуры результата — извлекать их вручную не требуется.

&НаКлиенте

Процедура ВыполнитьДлительнуюОперацию(Команда)

ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);

ПараметрыВыполнения.ЗапуститьВФоне = Истина;

Оповещение = Новый ОписаниеОповещения("ПослеЗавершенияОперации", ЭтотОбъект);

ДлительныеОперации.ВыполнитьВФоне(

"МойМодуль.ДлительнаяПроцедура",

Новый Структура("Период", ПериодОтчета),

ПараметрыВыполнения);

КонецПроцедуры

&НаКлиенте

Процедура ПослеЗавершенияОперации(Результат, ДопПараметры) Экспорт

Если Результат = Неопределено Тогда

Возврат;

КонецЕсли;

Если Результат.Статус = "Ошибка" Тогда

Сообщить(Результат.КраткоеПредставлениеОшибки);

КонецЕсли;

// сообщения из фонового задания

Для Каждого Сообщение Из Результат.Сообщения Цикл

Сообщение.Сообщить();

КонецЦикла;

КонецПроцедуры

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

Порядок действий без БСП
  1. 1
    Запустите задание через ФоновыеЗадания.Выполнить и сохраните возвращённый объект задания
  2. 2
    Дождитесь завершения через ОжидатьЗавершенияВыполнения или периодически проверяйте Состояние
  3. 3
    Проверьте Состояние: Завершено или ЗавершеноАварийно
  4. 4
    Вызовите Задание.ПолучитьСообщенияПользователю(Истина) и выведите массив сообщений
  5. 5
    При аварийном завершении дополнительно прочитайте ИнформацияОбОшибке

Как получать сообщения во время выполнения задания

Штатный буфер сообщений доступен только после завершения, но на практике для длительных загрузок и обработок нужен «живой» прогресс: какие документы обработаны, какие отклонены. Для этого фоновое задание должно само писать промежуточные данные в общедоступное хранилище, а клиент — периодически их считывать.

Типовые варианты такого обмена:

  • Регистр сведений. Задание записывает строки протокола (время, текст, уровень важности, ключ операции), клиент по таймеру читает новые записи. Подходит для протоколов, которые нужно хранить и после завершения.
  • Временное хранилище. Задание помещает промежуточный результат по адресу, известному клиенту; клиент опрашивает его через ПолучитьИзВременногоХранилища. Данные живут ограниченное время и не засоряют базу.
  • Константа или параметр сеанса — для передачи одного значения прогресса (процент выполнения), но не для потока сообщений.

При записи в регистр из фонового задания учитывайте транзакционность: пишите протокол отдельными небольшими транзакциями, чтобы записи становились видны клиенту сразу, а не только после завершения всей операции. Иначе эффект «живого» вывода пропадёт.

Сравнение вариантов

ПолучитьСообщенияПользователю

Простой ручной способ без БСП. Сообщения доступны только после завершения задания, клиент блокируется на время ожидания.

ДлительныеОперации (БСП)

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

Регистр сведений / временное хранилище

Единственный вариант для сообщений в процессе выполнения. Требует самостоятельной реализации записи и опроса, больше кода.

Типичные ошибки и ограничения

Типичные ошибки
01
Вызов ПолучитьСообщенияПользователю до завершения задания — буфер ещё не сформирован полностью, часть сообщений теряется из вывода
02
Потеря объекта задания: результат ФоновыеЗадания.Выполнить не сохранён, и обратиться к заданию потом можно только через ФоновыеЗадания.НайтиПоУникальномуИдентификатору
03
Вызов Сообщить() на клиенте в ожидании того, что сообщение уйдёт в фоновое задание — контексты не связаны, сообщение выводится только в текущем сеансе
04
Длительное блокирующее ожидание на клиенте — интерфейс зависает, у пользователя создаётся впечатление аварии
05
Игнорирование состояния ЗавершеноАварийно: сообщения читаются, а ИнформацияОбОшибке не проверяется, и причина сбоя остаётся невидимой

Ещё одно ограничение касается привязки сообщений к полям формы. Свойство ПутьКДанным объекта СообщениеПользователю, заполненное внутри фонового задания, относится к контексту серверного сеанса. При выводе на клиенте такая привязка обычно не срабатывает — сообщение отображается без «привязки» к полю формы. Если подсветка полей критична, передавайте структурированные данные об ошибках и формируйте сообщения уже на клиенте.

Также помните, что фоновое задание не имеет доступа к данным формы клиентского сеанса. Все входные параметры нужно передавать явно через массив параметров при запуске, причём они должны быть сериализуемыми — объекты типа ДанныеФормы передать нельзя.

Проверка результата и отладка

Чтобы убедиться, что механизм работает, добавьте в фоновую процедуру несколько контрольных сообщений на ключевых этапах: старт, обработано N записей, завершение. После первого запуска проверьте, что весь массив сообщений дошёл до клиента, а состояние задания корректно определяется.

Контрольные точки

Как проверить результат

Состояние задания после запуска
Норма

Состояние = Завершено, сообщения получены массивом

Тревожный признак

Состояние = ЗавершеноАварийно или задание «висит» в состоянии Активно дольше ожидаемого

Содержимое массива сообщений
Норма

Присутствуют все контрольные сообщения в правильном порядке

Тревожный признак

Массив пуст или сообщений меньше, чем выводилось в коде — проверьте, что чтение выполняется после завершения

Повторный запуск
Норма

Сообщения не дублируются благодаря очистке буфера параметром Истина

Тревожный признак

При каждом запуске выводятся сообщения прошлых запусков

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

Итог

Что важно запомнить

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

Частые вопросы

Можно ли получить сообщения фонового задания, не дожидаясь его завершения?

Штатным методом ПолучитьСообщенияПользователю — нет, буфер доступен после завершения. Для промежуточного вывода организуйте запись протокола из фонового задания в регистр сведений или временное хранилище и периодически опрашивайте его с клиента.

Что делать, если ПолучитьСообщенияПользователю возвращает пустой массив?

Проверьте три момента: задание действительно завершилось (а не активно), сообщения выводятся именно внутри фоновой процедуры, а не в вызывающем коде, и буфер не был очищен предыдущим вызовом с параметром Истина.

Как найти объект задания, если ссылка на него потеряна?

Используйте ФоновыеЗадания.НайтиПоУникальномуИдентификатору, если сохранён УникальныйИдентификатор задания, либо ФоновыеЗадания.ПолучитьФоновыеЗадания с отбором по наименованию или состоянию. Поэтому уникальный идентификатор задания полезно сохранять сразу после запуска.

Работает ли ДлительныеОперации в самописной конфигурации без БСП?

Нет, это программный интерфейс библиотеки стандартных подсистем. Если БСП не внедрена, используйте прямую работу с ФоновыеЗадания.Выполнить и ПолучитьСообщенияПользователю либо внедрите подсистему «Длительные операции» из БСП.

Почему сообщения из фонового задания не привязываются к полям формы?

Свойство ПутьКДанным заполняется в контексте серверного сеанса фонового задания, где нет клиентской формы. Для подсветки полей передавайте из задания структуру с описанием ошибок и формируйте СообщениеПользователю с привязкой уже на клиенте, в контексте нужной формы.

Где смотреть ошибки фоновых заданий, если сообщений недостаточно?

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