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