Как правильно запустить фоновое задание в 1С 8.3 и передать в него параметры?

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

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

Разберем механизм работы фоновых заданий

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

Проанализируем базовый синтаксис метода Выполнить объекта ФоновыеЗадания. Этот метод принимает на вход имя процедуры, параметры, уникальный ключ и наименование задания. Мы рекомендуем всегда задавать понятное наименование, чтобы в консоли кластера или в типовой обработке "Регламентные и фоновые задания" администратор мог идентифицировать процесс.

Запуск простейшего фонового задания

Рассмотрим пример, когда нам нужно запустить процедуру без параметров. Представим, что у нас есть общий модуль ДлительныеОперацииСервер, в котором объявлена процедура ВыполнитьПересчетДанных.


// Код на стороне клиента или сервера
ИмяПроцедуры = "ДлительныеОперацииСервер.ВыполнитьПересчетДанных";
Задание = ФоновыеЗадания.Выполнить(ИмяПроцедуры, , , "Пересчет данных в фоне");

В данном примере мы создаем задание, которое немедленно ставится в очередь на выполнение. Переменная Задание будет содержать объект типа ФоновоеЗадание, через который мы сможем в дальнейшем получать информацию о статусе выполнения.

Как правильно передавать параметры в фоновое задание

Выясним причину частых ошибок новичков при передаче параметров. Параметры в метод Выполнить должны передаваться в виде Массива. Порядок элементов в массиве должен строго соответствовать порядку аргументов в вызываемой процедуре. Разберем ситуацию на примере передачи структуры с настройками.

Предположим, наша процедура имеет следующий заголовок:


Процедура ОбработатьЗагрузку(ПараметрыЗагрузки, СкладНазначения) Экспорт
    // Логика обработки
КонецПроцедуры

Для корректного вызова нам необходимо сформировать массив следующим образом:


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

СтруктураНастроек = Новый Структура;
СтруктураНастроек.Вставить("ДатаНачала", Объект.ДатаНачала);
СтруктураНастроек.Вставить("РежимОтладки", Истина);

ПараметрыПроцедуры.Добавить(СтруктураНастроек); // Первый параметр
ПараметрыПроцедуры.Добавить(Объект.Склад);      // Второй параметр

ИмяПроцедуры = "ОбменДаннымиСервер.ОбработатьЗагрузку";
Задание = ФоновыеЗадания.Выполнить(ИмяПроцедуры, ПараметрыПроцедуры);

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

Ожидание завершения и получение результата

Зачастую недостаточно просто запустить процесс — нам нужно дождаться его окончания и, возможно, забрать результат. Рассмотрим, как это реализовать с помощью метода ОжидатьЗавершения. Этот метод блокирует текущий поток выполнения до тех пор, пока задание не завершится или не истечет время таймаута.


МассивЗаданий = Новый Массив;
МассивЗаданий.Добавить(Задание);

Попытка
    ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий, 60); // Ждем 60 секунд
    Сообщить("Задание успешно выполнено!");
Исключение
    Сообщить("Произошла ошибка при выполнении или время вышло");
КонецПопытки

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

  1. Запускаем фоновое задание на сервере и возвращаем его УникальныйИдентификатор на клиент.
  2. На клиенте запускаем обработчик ожидания (например, раз в 2-3 секунды).
  3. В обработчике проверяем свойство Состояние фонового задания по его идентификатору.
  4. Когда состояние становится Завершено или ЗавершеноСОшибкой, отключаем обработчик и выводим результат.

Использование временного хранилища для передачи больших данных

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

Посмотрим на пример реализации:


// На стороне инициатора
АдресДанных = ПоместитьВоВременноеХранилище(ТаблицаДанных, Новый УникальныйИдентификатор());
Параметры = Новый Массив;
Параметры.Добавить(АдресДанных);
ФоновыеЗадания.Выполнить("МойМодуль.ОбработатьДанныеИзХранилища", Параметры);

// В общем модуле
Процедура ОбработатьДанныеИзХранилища(АдресДанных) Экспорт
    Данные = ПолучитьИзВременногоХранилища(АдресДанных);
    // Обработка данных
КонецПроцедуры

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

Обработка ошибок в фоновых заданиях

Проанализируем, как узнать, что пошло не так. Если в коде фонового задания произойдет исключение, оно не "вывалится" в интерфейс пользователя. Чтобы получить текст ошибки, нам нужно обратиться к свойству ИнформацияОбОшибке объекта ФоновоеЗадание.

Рекомендуем всегда использовать конструкцию Попытка...Исключение внутри кода фонового задания и записывать критические ошибки в ЖурналРегистрации с помощью метода ЗаписатьСобытиеЖурналаРегистрации. Это значительно упростит диагностику проблем в будущем.

Подведем итоги

Мы рассмотрели ключевые аспекты работы с фоновыми заданиями. Использование этого механизма позволяет:

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

← На главную