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