Почему фоновое задание в 1С зависает в статусе "Выполняется" и как получить данные из временного хранилища?

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

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

Постановка задачи и анализ исходного кода

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

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


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

Код выглядит абсолютно логичным: мы генерируем уникальный идентификатор УИН, резервируем адрес во временном хранилище с помощью функции ПоместитьВоВременноеХранилище и передаем этот адрес параметром в метод ФоновыеЗадания.Выполнить. Внутри фоновой процедуры результат помещается по этому адресу. Однако при попытке прочитать данные из родительского сеанса сразу после запуска задания — хранилище оказывается пустым, а статус задания зависает.

Причина 1: Особенности временного хранилища и асинхронности

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

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

Причина 2: Жизненный цикл сеанса на кластере (rmngr и rphost)

Выясним причину, по которой задание остается в статусе "Выполняется", хотя мы видим в отладчике, что код процедуры завершен. Ситуация связана с механикой закрытия сеансов. После выполнения последней строчки вашего кода рабочий процесс сервера 1С (rphost) выполняет ряд системных действий:

  1. Фиксирует или откатывает скрытые системные транзакции.
  2. Перемещает подготовленные данные временного хранилища в общую память менеджера кластера (rmngr).
  3. Отправляет уведомление планировщику заданий о том, что поток свободен.
  4. Уничтожает системный контекст сеанса.

Если на сервер 1С оказывается высокая нагрузка, имеются проблемы с кэшем или блокировки на стороне СУБД, этот процесс финализации может "подвисать". Задержка может составлять от нескольких секунд до десятков минут.

Причина 3: Влияние отладчика

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

Причина 4: Специфика Обычных Форм (ОФ)

Так как мы рассматриваем контекст Обычных Форм (толстый клиент), нужно учитывать особенности сборщика мусора 1С. Механизм передачи данных через временное хранилище с использованием УникальныйИдентификатор проектировался в первую очередь под архитектуру Управляемых Форм, где адрес жестко привязывается к идентификатору серверной формы.

В обычных формах, если УИН жестко не привязан к "живой" форме (у которой есть серверный контекст), сборщик мусора платформы может уничтожить данные во временном хранилище практически мгновенно после того, как фоновое задание их туда поместит и завершится. Это еще одна причина, почему при чтении вы можете получить пустой результат.

Решение проблемы: Синхронизация и метод ОжидатьЗавершения

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

Рассмотрим решение с использованием метода ОжидатьЗавершения:


// ... код запуска задания ...
Задание = ФоновыеЗадания.Выполнить("УправлениеЗаказами.ПолучитьТаблицуЗон", ПараметрыЗадания);

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

// Теперь можно безопасно читать данные из временного хранилища
Результат = ПолучитьИзВременногоХранилища(АдресРезультатаФоновогоЗадания);

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

Что делать, если сеанс завис окончательно?

Если после добавления ожидания задание висит в статусе "Выполняется" часами, это сигнализирует о серьезном сбое внутри рабочего процесса сервера 1С. Обычно это связано с "мертвыми" блокировками SQL или зависанием сетевых соединений. Самостоятельно платформа такие зависшие (зомби) задания не убивает.

В этом случае вам потребуется административное вмешательство:

  1. Откройте Консоль администрирования серверов 1С:Предприятия.
  2. Перейдите в раздел Сеансы нужной информационной базы.
  3. Найдите сеанс с приложением Фоновое задание, который висит дольше положенного времени.
  4. Вручную удалите этот сеанс.
  5. Если удаление сеанса не помогает, может потребоваться перезапуск рабочего процесса (rphost), в котором повисло задание.

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

← На главную