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

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

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

Зачем использовать фоновые задания

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

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

Подготовка серверной процедуры

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

Рассмотрим пример процедуры, которая выполняет длительный расчет:


Процедура ВыполнитьДлительныйРасчет(ПараметрыРасчета, АдресХранилища) Экспорт
    // Проанализируем переданные параметры
    Организация = ПараметрыРасчета.Организация;
    Период = ПараметрыРасчета.Период;
    
    // Имитация длительной работы
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 100 Ссылка ИЗ Справочник.Номенклатура";
    Результат = Запрос.Выполнить().Выгрузить();
    
    // Поместим результат во временное хранилище, чтобы клиент мог его забрать
    ПоместитьВоВременноеХранилище(Результат, АдресХранилища);
КонецПроцедуры

Запуск задания с передачей параметров

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

  1. Подготовим структуру параметров для расчета.
  2. Создадим уникальный идентификатор для ВременноеХранилище.
  3. Сформируем массив параметров для передачи в фоновое задание.
  4. Вызовем метод выполнения.

Посмотрим на пример кода запуска задания:


&НаСервере
Функция ЗапуститьЗаданиеНаСервере()
    // 1. Подготовка параметров
    ПараметрыСтруктура = Новый Структура;
    ПараметрыСтруктура.Вставить("Организация", Объект.Организация);
    ПараметрыСтруктура.Вставить("Период", Объект.Период);
    
    // 2. Подготовка хранилища для результата
    АдресРезультата = ПоместитьВоВременноеХранилище(Неопределено, ЭтаФорма.УникальныйИдентификатор);
    
    // 3. Массив параметров должен соответствовать параметрам экспортной процедуры
    МассивПараметров = Новый Массив;
    МассивПараметров.Добавить(ПараметрыСтруктура);
    МассивПараметров.Добавить(АдресРезультата);
    
    // 4. Запуск
    НаименованиеЗадания = "Расчет данных: " + ТекущаяДата();
    Задание = ФоновыеЗадания.Выполнить("МойОбщийМодуль.ВыполнитьДлительныйРасчет", 
                                       МассивПараметров, 
                                       Новый УникальныйИдентификатор, 
                                       НаименованиеЗадания);
    
    Возврат Новый Структура("ИдентификаторЗадания, АдресРезультата", Задание.УникальныйИдентификатор, АдресРезультата);
КонецФункции

Мониторинг состояния и получение результата

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

Разберем логику проверки:


&НаКлиенте
Процедура ПроверитьСтатусЗадания()
    Если ЗаданиеВыполнено(ИдентификаторЗадания) Тогда
        ОтключитьОбработчикОжидания("ПроверитьСтатусЗадания");
        ПолучитьРезультатИзХранилища();
    КонецЕсли;
КонецПроцедуры

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

Важные технические нюансы

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

Во-вторых, параметры, передаваемые в фоновое задание, должны быть сериализуемыми. Вы не можете передать в массив параметров ДанныеФормыСтруктура или саму форму. Используйте простые типы, структуры, таблицы значений или ссылки.

Проанализируем также вопрос управления памятью. Если вы используете ВременноеХранилище, обязательно привязывайте его к уникальному идентификатору формы, как показано в примере выше. Это гарантирует, что данные будут автоматически очищены после закрытия формы, не перегружая память сервера rphost.

Резюме по шагам

Подведем итог нашей совместной работы по внедрению асинхронности в 1С:

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

Используя данный подход, вы сможете значительно повысить производительность и стабильность ваших решений на платформе 1С.

← На главную