Разработка и Конфигурация · 10 мин
Как получить текущее фоновое задание в 1С
Как в 1С получить текущее фоновое задание из кода: методы ПолучитьФоновыеЗадания, Ключ, УникальныйИдентификатор, отборы, примеры кода и типичные ошибки.
При работе с фоновыми заданиями в 1С часто возникает задача: из кода определить, какое фоновое задание выполняется прямо сейчас, найти его по ключу или имени метода, проверить состояние и при необходимости отменить. Для этого в платформе предусмотрен менеджер фоновых заданий ФоновыеЗадания и объект ФоновоеЗадание с набором свойств и методов.
Главный инструмент — метод ФоновыеЗадания.ПолучитьФоновыеЗадания(), который возвращает массив объектов ФоновоеЗадание по заданному отбору. Отдельного метода «ПолучитьТекущееФоновоеЗадание» в языке нет, поэтому «текущее» задание определяют либо по отбору с состоянием Активно, либо передают в фоновый метод его собственный уникальный идентификатор.
Что такое фоновое задание и зачем его получать
Фоновое задание — это процедура или функция общего модуля, запущенная платформой асинхронно, в отдельном сеансе. Оно позволяет выполнять длительные операции (загрузку данных, расчёты, обмены) без блокировки пользовательского интерфейса.
Получать ссылку на объект фонового задания нужно в типовых сценариях: дождаться завершения через ОжидатьЗавершенияВыполнения(), отменить выполнение методом Отменить(), прочитать сообщения пользователю, проверить, не запущено ли уже такое же задание, чтобы не создать дубликат.
Как получить текущее фоновое задание через отбор
Метод ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор) принимает структуру отбора. Если вызвать его без параметров, вернутся все фоновые задания информационной базы — это медленно и в прикладном коде почти никогда не нужно.
Чтобы получить именно активные (выполняющиеся сейчас) задания, используют отбор по свойству Состояние со значением СостояниеФоновогоЗадания.Активно:
Отбор = Новый Структура;
Отбор.Вставить("Состояние", СостояниеФоновогоЗадания.Активно);
АктивныеЗадания = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
Для Каждого Задание Из АктивныеЗадания Цикл
Сообщить(Задание.Наименование + " — " + Задание.ИмяМетода);
КонецЦикла;
В отборе можно комбинировать поля: ИмяМетода, Ключ, Наименование, УникальныйИдентификатор, Состояние. Например, чтобы проверить, не выполняется ли уже задание с тем же ключом:
Отбор = Новый Структура;
Отбор.Вставить("Ключ", "ЗагрузкаКурсовВалют");
Отбор.Вставить("Состояние", СостояниеФоновогоЗадания.Активно);
Если ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор).Количество() > 0 Тогда
// Задание уже выполняется, повторно не запускаем
КонецЕсли;
Как фоновому заданию получить само себя
Внутри фоновой процедуры нет встроенного способа напрямую узнать «самого себя» как объекта. Стандартный приём — передать в фоновый метод его уникальный идентификатор или ключ параметром, а затем найти задание отбором.
// Код, запускающий задание
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(Новый УникальныйИдентификатор);
Задание = ФоновыеЗадания.Выполнить(
"МойМодуль.ДлительнаяОперация",
ПараметрыЗадания, "МойКлюч", "Длительная операция");
Более надёжный вариант — сначала сгенерировать идентификатор, передать его в параметры, а внутри фонового метода найти себя по этому идентификатору:
Процедура ДлительнаяОперация(ИдентификаторЗадания) Экспорт
Отбор = Новый Структура("УникальныйИдентификатор", ИдентификаторЗадания);
Найденные = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
Если Найденные.Количество() > 0 Тогда
ТекущееЗадание = Найденные[0];
// Теперь доступны состояние, сообщения и др.
КонецЕсли;
КонецПроцедуры
- 1Сгенерируйте уникальный идентификатор или задайте осмысленный ключ
- 2Передайте его параметром в фоновый метод через ФоновыеЗадания.Выполнить()
- 3Внутри фоновой процедуры выполните отбор по УникальныйИдентификатор или Ключ
- 4Возьмите первый элемент массива — это текущее задание
- 5Проверьте Состояние и ИнформацияОбОшибке перед использованием результатов
Какие свойства доступны у объекта ФоновоеЗадание
Полученный объект ФоновоеЗадание содержит всю информацию о выполнении. Основные свойства:
УникальныйИдентификатор— GUID задания, присваивается платформой;Ключ— произвольная строка, задаётся при запуске, удобна для поиска дублей;Наименование— человекочитаемое описание;ИмяМетода— имя вызываемой процедуры или функции;Состояние— значение перечисленияСостояниеФоновогоЗадания: Активно, Завершено, ЗавершеноАварийно, Отменено;НачалоиКонец— даты старта и завершения;ИнформацияОбОшибке— объект с описанием ошибки, если задание завершилось аварийно;РегламентноеЗадание— ссылка на регламентное задание, если фоновое порождено им.
Отдельно полезен метод ПолучитьСообщенияПользователю() — он возвращает массив сообщений, выведенных внутри фонового задания через Сообщить(). Это стандартный способ передать из фонового кода диагностику или результат пользователю.
Если Задание.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда
Описание = Задание.ИнформацияОбОшибке.Описание;
ЗаписьЖурналаРегистрации("ФоновоеЗадание", УровеньЖурналаРегистрации.Ошибка,,, Описание);
КонецЕсли;Ожидание завершения и отмена задания
Если нужно дождаться окончания текущего задания, используйте метод ОжидатьЗавершенияВыполнения(Таймаут). Он блокирует выполнение кода до завершения задания или истечения таймаута, поэтому в клиентском коде его применяют осторожно — интерфейс зависнет.
Задание.ОжидатьЗавершенияВыполнения(60); // ждём не более 60 секунд
Если Задание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда
// Обрабатываем результат
КонецЕсли;
Для отмены активного задания вызывается Задание.Отменить(). Отмена происходит не мгновенно: платформа прерывает выполнение в ближайшей безопасной точке, и состояние меняется на Отменено. В клиент-серверном режиме для отмены требуются права администрирования.
Поиск задания по регламентному заданию
Фоновые задания, запущенные регламентными, тоже находятся через общий отбор. Удобнее всего искать по свойству РегламентноеЗадание:
Регламентное = РегламентныеЗадания.НайтиПоУникальномуИдентификатору(ИД);
Отбор = Новый Структура;
Отбор.Вставить("РегламентноеЗадание", Регламентное);
Отбор.Вставить("Состояние", СостояниеФоновогоЗадания.Активно);
Активные = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
Такой приём используют, чтобы проверить, не зависло ли регламентное задание, или чтобы не запустить второй экземпляр метода, пока первый ещё работает.
Частые ошибки и ограничения
Первая распространённая ошибка — попытка получить «текущее» задание, полагаясь на порядок в массиве. Метод возвращает задания в порядке, который не гарантирует, что первый элемент — нужный. Всегда сужайте отбор до уникального значения: ключ, идентификатор, имя метода плюс состояние.
Вторая ошибка — работа с фоновыми заданиями из внешних обработок без учёта контекста сервера. Методы менеджера фоновых заданий доступны на сервере; на тонком клиенте прямой вызов недоступен, нужен серверный вызов.
Также помните об ограничениях: фоновые задания не имеют права запускать другие фоновые задания в некоторых режимах (зависит от версии платформы и настроек), а в файловой базе количество одновременно выполняющихся заданий ограничено. Проверяйте документацию под свою версию платформы.
Как проверить результат
Массив содержит ровно одно задание с нужным ключом
Пустой массив или несколько заданий — отбор недостаточно точный
Активно или Завершено в ожидаемый момент времени
ЗавершеноАварийно — смотрите ИнформацияОбОшибке
ПолучитьСообщенияПользователю() возвращает ожидаемые сообщения
Пустой массив — в фоновом коде не вызывался Сообщить()
Итог
Получить текущее фоновое задание в 1С — значит выполнить отбор через ФоновыеЗадания.ПолучитьФоновыеЗадания() по состоянию, ключу, имени метода или уникальному идентификатору. Для самоидентификации задания его идентификатор передают параметром в фоновую процедуру. Полученный объект позволяет проверить состояние, дождаться завершения, отменить выполнение и прочитать сообщения или информацию об ошибке.
Что важно запомнить
Отдельного метода «получить текущее задание» нет: используйте ПолучитьФоновыеЗадания() с точным отбором по ключу или идентификатору, всегда проверяйте количество найденных элементов и состояние задания перед работой с результатом.
Часто задаваемые вопросы
Можно ли получить фоновое задание по имени метода?
Да, в отборе есть поле ИмяМетода. Однако по одному имени могут выполняться несколько экземпляров, поэтому имя метода лучше комбинировать с состоянием Активно или ключом.
Почему ПолучитьФоновыеЗадания возвращает пустой массив, хотя задание запущено?
Чаще всего отбор слишком строгий: не совпадает ключ, регистр букв в имени метода или задание уже завершилось, а в отборе указано состояние Активно. Проверьте параметры отбора и актуальное состояние.
Как узнать, что фоновое задание завершилось с ошибкой?
Проверьте свойство Состояние: значение ЗавершеноАварийно означает ошибку. Подробное описание доступно в свойстве ИнформацияОбОшибке, которое можно записать в журнал регистрации.
Можно ли вызвать ПолучитьФоновыеЗадания на клиенте?
Нет, менеджер фоновых заданий доступен только в серверном контексте. На тонком или веб-клиенте нужно вызывать серверную процедуру, которая выполнит отбор и вернёт нужные данные.
Чем ключ отличается от уникального идентификатора задания?
Ключ — произвольная строка, которую задаёт разработчик при запуске; он не обязан быть уникальным и удобен для поиска дублей. Уникальный идентификатор присваивается платформой и гарантированно уникален.
Как не запустить второй экземпляр одного и того же задания?
Перед вызовом ФоновыеЗадания.Выполнить() выполните отбор по ключу и состоянию Активно. Если найдено хотя бы одно активное задание с этим ключом, повторный запуск пропускают.