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

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

Как создать фоновое задание в 1С

Как создать фоновое задание в 1С: код метода ФоновыеЗадания.Выполнить, параметры, ожидание завершения, расписание регламентных заданий и типичные ошибки.

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

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

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

Что нужно подготовить перед созданием задания

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

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

Создаём общий модуль и процедуру

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

Добавьте в модуль экспортную процедуру, которая будет выполнять полезную работу. Пример — длительная обработка документов:

Процедура ОбработатьДокументы(ДатаНачала, ДатаОкончания) Экспорт

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Документ.Реализация

|ГДЕ Дата МЕЖДУ &Начало И &Конец";

Запрос.УстановитьПараметр("Начало", ДатаНачала);

Запрос.УстановитьПараметр("Конец", ДатаОкончания);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

// логика обработки

КонецЦикла;

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

Обратите внимание: внутри процедуры нельзя использовать Предупреждение(), Вопрос(), открытие форм. Ошибки следует записывать в журнал регистрации через ЗаписьЖурналаРегистрации(), чтобы потом разобраться, что пошло не так.

Запускаем задание программно

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

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

ПараметрыПроцедуры.Добавить(НачалоМесяца(ТекущаяДата()));

ПараметрыПроцедуры.Добавить(КонецМесяца(ТекущаяДата()));

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

"ФоновыеОперации.ОбработатьДокументы",

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

"ОбработкаДокументов_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd"),

"Обработка документов за месяц");

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

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

Ключ задания и контроль дублей

Ключ — строковый идентификатор, который позволяет найти задание и предотвратить повторный запуск. Если вызвать ФоновыеЗадания.Выполнить() с ключом, по которому уже выполняется активное задание, платформа выдаст ошибку. Это удобный механизм защиты от дублирования тяжёлых операций.

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

Типичные ошибки
01
Процедура размещена в модуле формы — платформа выдаёт ошибку «Метод не обнаружен», перенесите код в общий серверный модуль
02
Пропущено слово Экспорт — метод недоступен для вызова извне модуля
03
Использование немодальных диалогов внутри задания — ошибка на сервере, замените на запись в журнал регистрации
04
Передача несериализуемых параметров (ТабличныйДокумент, COMОбъект) — исключение при старте задания
05
Игнорирование ключа — пользователь запускает десять одинаковых тяжёлых заданий и перегружает сервер

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

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

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

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

bsl
Задание = ФоновыеЗадания.Выполнить("ФоновыеОперации.ОбработатьДокументы", ПараметрыПроцедуры, Ключ, Наименование);
Задание = Задание.ОжидатьЗавершенияВыполнения(60);
Если Задание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда
	Результат = ПолучитьИзВременногоХранилища(АдресХранилища);
ИначеЕсли Задание.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда
	ВызватьИсключение Задание.ИнформацияОбОшибке.Описание;
КонецЕсли;

Регламентные задания: запуск по расписанию

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

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

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

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

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

Разовый запуск по действию пользователя, гибкие параметры, ручной контроль состояния

Регламентное задание

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

Длительные операции БСП

Фоновый запуск с готовым индикатором прогресса и уведомлением формы; доступно только в конфигурациях на БСП

Мониторинг, отладка и ограничения

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

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

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

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

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

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

Завершено, ошибок нет

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

ЗавершеноАварийно — смотрите ИнформацияОбОшибке и журнал регистрации

Данные в базе
Норма

Ожидаемые объекты созданы или изменены

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

Изменений нет — проверьте параметры и права пользователя, под которым работало задание

Журнал регистрации
Норма

Нет ошибок по событию задания

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

Ошибки доступа, блокировок или «метод не обнаружен»

Частые вопросы о фоновых заданиях

Почему возникает ошибка «Метод объекта не обнаружен»?

Чаще всего процедура находится не в общем серверном модуле, не объявлена с ключевым словом Экспорт или имя в строке вызова не совпадает с реальным. Проверьте формат «ИмяОбщегоМодуля.ИмяПроцедуры» и свойства модуля.

Можно ли отменить запущенное фоновое задание?

Да, методом Отменить() у объекта задания или кнопкой «Отменить» в консоли заданий. Учтите, что отмена прерывает выполнение принудительно: незавершённые транзакции откатятся, но уже зафиксированные изменения останутся.

Как передать результат работы задания на клиента?

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

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

В файловом режиме нет сервера, который запускал бы задания. Нужен сеанс с выполняющимся методом ВыполнитьОбработкуЗаданий() либо запуск отдельного сеанса с параметром ExecuteScheduledJobs. В серверном режиме такой проблемы нет.

Сколько фоновых заданий можно запустить одновременно?

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

Чем фоновое задание отличается от регламентного?

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

Итог

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

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