При работе в управляемом приложении 1С 8.3 пользователи часто сталкиваются с ситуацией, когда выполнение тяжелого отчета или обработки «замораживает» интерфейс. Для решения этой проблемы в платформе предусмотрен механизм фоновых заданий. В данной статье мы разберем, как правильно перенести выполнение кода на сторону сервера в асинхронном режиме, обеспечив комфортную работу пользователя.
Проанализируем основную причину использования этого механизма. В управляемых формах основной поток исполнения отвечает за интерфейс. Если запустить в нем процедуру, которая длится более нескольких секунд, операционная система пометит окно программы как «не отвечающее». Использование фоновых заданий позволяет:
Прежде чем мы перейдем к коду, важно уяснить несколько правил. Процедура, которую мы планируем запустить в фоне, должна располагаться в общем модуле. К этому модулю предъявляются следующие требования:
Предупреждение() или Вопрос()).Рассмотрим пример кода, который инициирует выполнение задачи на сервере. Для этого используется объект ФоновыеЗаданияМенеджер. Выясним, как передать параметры в процедуру.
// Пример запуска процедуры из общего модуля "ДлительныеПроцедуры"
ИмяПроцедуры = "ДлительныеПроцедуры.ВыполнитьТяжелыйРасчет";
// Параметры передаются в виде массива в строгом соответствии с заголовком процедуры
ПараметрыПроцедуры = Новый Массив;
ПараметрыПроцедуры.Добавить(Объект.Ссылка);
ПараметрыПроцедуры.Добавить(ТекущаяДата());
// Запускаем задание
Задание = ФоновыеЗадания.Выполнить(ИмяПроцедуры, ПараметрыПроцедуры, Новый УникальныйИдентификатор, "Запуск расчета из формы");
В данном примере функция Выполнить принимает имя процедуры, массив параметров, уникальный идентификатор задания и строковое описание, которое будет отображаться в консоли кластера 1С.
После запуска задания нам необходимо понимать, когда оно завершится. Разберем, как организовать проверку состояния из формы. Обычно для этого используется обработчик ожидания.
Сначала в форме настроим периодическую проверку:
&НаКлиенте
Процедура НачатьРасчет(Команда)
ИдентификаторЗадания = ЗапуститьЗаданиеНаСервере();
ПодключитьОбработчикОжидания("ПроверитьЗавершениеЗадания", 2); // Проверка каждые 2 секунды
КонецПроцедуры
Теперь проанализируем процедуру проверки состояния. Мы должны проверить свойство Состояние объекта ФоновоеЗадание.
&НаСервереБезКонтекста
Функция ПолучитьСостояниеЗадания(ИдентификаторЗадания)
Задание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторЗадания);
Если Задание <> Неопределено Тогда
Возврат Строка(Задание.Состояние);
КонецЕсли;
Возврат "НеНайдено";
КонецФункции
Важно помнить, что если в фоновом задании произошла ошибка, его состояние станет ЗавершеноАварийно. В этом случае полезно проанализировать описание ошибки через свойство ИнформацияОбОшибке.
Если ваша конфигурация построена на базе БСП (например, УТ 11, ERP, БП 3.0), рекомендуется использовать подсистему ДлительныеОперации. Это значительно упрощает обработку прогресса и получение результата. Рассмотрим, как это сделать.
Запуск операции с помощью БСП выглядит следующим образом:
&НаСервере
Функция ЗапуститьОперациюБСП()
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
ПараметрыВыполнения.НаименованиеФоновогоЗадания = "Расчет сложных показателей";
Результат = ДлительныеОперации.ВыполнитьВФоне("МойОбщийМодуль.Процедура", ПараметрыПроцедуры, ПараметрыВыполнения);
Возврат Результат;
КонецФункции
Механизм БСП автоматически обрабатывает хранение временных результатов и предоставляет удобные методы для ожидания завершения через ДлительныеОперацииКлиент.ОжидатьЗавершения, что избавляет разработчика от ручного написания обработчиков ожидания.
Фоновое задание работает в отдельном сеансе, поэтому оно не может напрямую менять реквизиты открытой формы. Посмотрим на способы передачи данных назад:
ПоместитьВоВременноеХранилище(Данные, Адрес). Адрес нужно передать заранее.Разберем пример с использованием временного хранилища. Чтобы фоновое задание могло записать туда данные, адрес хранилища должен быть создан в основном сеансе и передан как один из параметров в фоновую процедуру.
// В фоновой процедуре
Процедура ВыполнитьТяжелыйРасчет(АдресХранилища) Экспорт
Результат = "Данные рассчитаны!";
ПоместитьВоВременноеХранилище(Результат, АдресХранилища);
КонецПроцедуры
Поскольку фоновое задание выполняется в отдельном процессе, обычная точка останова в конфигураторе может не сработать. Для отладки выполним следующие действия:
-debug.Только после выполнения этих шагов отладчик «подцепит» новый сеанс фонового задания, и вы сможете проанализировать логику работы по шагам.
Мы рассмотрели основы работы с фоновыми заданиями в 1С 8.3. Этот инструмент является мощным средством оптимизации UX (User Experience). Правильное разделение логики на «интерфейсную» и «вычислительную» части позволяет создавать быстрые и отзывчивые приложения даже при обработке огромных массивов данных. Помните о необходимости корректной обработки ошибок и всегда информируйте пользователя о статусе выполнения длительной операции.