Как передать файл или двоичные данные в фоновое задание 1С?

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

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

Почему временное хранилище «теряет» данные в фоновом задании

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

Рассмотрим основные причины очистки хранилища:

  1. Разрыв сеансовой связи: Если при помещении данных не был указан уникальный идентификатор, живущий дольше одного серверного вызова, данные могут быть удалены до того, как фоновое задание успеет к ним обратиться.
  2. Изоляция сеансов: Фоновое задание работает в своей «песочнице». Даже если вы передадите адрес строки ВХ, попытка получить данные по этому адресу в другом сеансе вернет пустоту.
  3. Кластерная среда: В многосерверных кластерах основной сеанс и фоновое задание могут физически исполняться на разных рабочих серверах (разных rphost), что еще сильнее усложняет прямой доступ к оперативной памяти другого процесса.

Способ 1: Прямая передача объекта ДвоичныеДанные в параметрах

Как показывает практика и обсуждение на форуме, это самый надежный и простой способ для файлов небольшого и среднего размера (до 20-50 Мб). Платформа 1С позволяет передавать объект типа ДвоичныеДанные непосредственно в массиве параметров фонового задания. При этом происходит сериализация данных в XML и их передача в новый сеанс.

Рассмотрим пример реализации. Сначала получим данные файла на сервере, а затем передадим их в задание:


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

В процедуре фонового задания в общем модуле (с установленными флажками «Сервер» и «Вызов сервера»):


Процедура ОбработатьФайлВФоне(ДанныеФайла) Экспорт
    
    // Здесь ДанныеФайла — это полноценный объект ДвоичныеДанные
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
    ДанныеФайла.Записать(ИмяВременногоФайла);
    
    // Далее выполняем логику обработки файла...
    
КонецПроцедуры

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

Способ 2: Использование ХранилищаЗначения в базе данных

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

Разберем алгоритм по шагам:

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

Пример кода для записи:


&НаСервере
Функция ПередатьФайлЧерезБД(ДанныеФайла)
    
    НоваяЗапись = Справочники.ВременныеДанные.СоздатьЭлемент();
    НоваяЗапись.Данные = Новый ХранилищеЗначения(ДанныеФайла, Новый СжатиеДанных(9));
    НоваяЗапись.ДатаСоздания = ТекущаяДата();
    НоваяЗапись.Записать();
    
    Возврат НоваяЗапись.Ссылка;
    
КонецФункции

Этот метод гарантирует, что данные будут доступны на любом сервере кластера, так как они считываются из СУБД, а не из оперативной памяти конкретного процесса.

Способ 3: Получение результата из фонового задания через АдресРезультата

Иногда задача стоит иначе: фоновое задание должно сформировать файл и вернуть его пользователю. Рассмотрим ситуацию, описанную в сообщении 15. Для этого используется механизм передачи УникальныйИдентификатор формы в фоновое задание, чтобы задание могло «положить» результат в хранилище, привязанное к этой форме. Для организации такого взаимодействия без использования стандартных библиотек подойдёт пример реализации длительных операций и отслеживания результата фоновых заданий без БСП.


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

Внутри фонового задания результат помещается так:


Процедура Сформировать(АдресРезультата) Экспорт
    Результат = Новый ДвоичныеДанные(ПутьКФайлу);
    ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецПроцедуры

Рекомендации и выводы

Подводя итог нашему анализу, выделим основные правила работы с файлами в фоновых заданиях:

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

← На главную