Как правильно реализовать длительную операцию с выводом прогресс-бара в 1С при помощи БСП?

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

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

Проблема ручной реализации и почему старый подход неэффективен

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

Выясним причину, почему такой подход считается ошибочным и не рекомендуется к использованию в современных версиях БСП:

  1. Метод устарел. Функция ДлительныеОперации.ВыполнитьВФоне признана устаревшей (deprecated). Вместо нее в современных версиях БСП (3.x и выше) используются специализированные методы ДлительныеОперации.ВыполнитьПроцедуру и ДлительныеОперации.ВыполнитьФункцию.
  2. Избыточность кода. Написание собственных обработчиков ожидания требует ручного контроля завершения фонового задания, обработки возможных ошибок и своевременного отключения обработчика ожидания. Это приводит к раздуванию кода формы.
  3. Проблемы с интерфейсом. Самостоятельное управление всплывающими окнами ожидания часто выглядит нетиповым, в то время как БСП предоставляет стандартизированный, аккуратный и привычный для пользователя интерфейс прогресс-бара.

Рассмотрим подробнее, как решить эту задачу правильно, используя современные стандарты БСП.

Современная концепция длительных операций в БСП

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

Разберем по шагам, как устроен этот процесс.

Шаг 1. Создание фонового метода на сервере

Прежде всего, нам нужно подготовить экспортный серверный метод, который будет выполнять ресурсоемкую задачу. Этот метод должен располагаться в модуле, доступном для фонового выполнения (например, в модуле объекта обработки, модуле менеджера или в общем серверном модуле).

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


Процедура ВыполнитьТяжелыйРасчет(Параметры, АдресРезультата) Экспорт
    
    ПределЦикла = Параметры.ПределЦикла;
    
    // Рассчитываем шаг, чтобы не перегружать систему частыми оповещениями
    ШагОповещения = Цел(ПределЦикла / 50); 
    Если ШагОповещения = 0 Тогда
        ШагОповещения = 1;
    КонецЕсли;
    
    Для Счетчик = 1 По ПределЦикла Цикл
        
        // Здесь выполняется полезная работа (например, обработка данных)
        // ...
        
        // Оповещаем клиентское приложение о текущем прогрессе
        Если Счетчик % ШагОповещения = 0 Тогда
            Процент = Окр(Счетчик * 100 / ПределЦикла);
            ТекстПояснения = СтрШаблон("Обработано объектов: %1 из %2", Счетчик, ПределЦикла);
            
            // Специализированный метод БСП автоматически доставит данные на клиент
            ДлительныеОперации.СообщитьПрогресс(Процент, ТекстПояснения);
        КонецЕсли;
        
    КонецЦикла;
    
    // Помещаем финальный результат во временное хранилище
    СтруктураРезультата = Новый Структура("Статус", "Успешно");
    ПоместитьВоВременноеХранилище(СтруктураРезультата, АдресРезультата);
    
КонецПроцедуры

В данном коде ключевым является использование метода ДлительныеОперации.СообщитьПрогресс. Он избавляет нас от необходимости вручную управлять адресом временного хранилища для передачи статуса выполнения.

Шаг 2. Запуск фоновой задачи и подключение ожидания на клиенте

Теперь перейдем к модулю формы нашей обработки. Нам нужно инициировать запуск фонового задания на сервере, настроить параметры отображения прогресс-бара и передать управление интерактивному окну БСП.

Посмотрим, как выглядит программный код запуска:


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

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

Обратите внимание на свойство ПараметрыОжидания.ВыводитьПрогрессВыполнения. Установка его в значение Истина является ключевым действием, которое заставляет БСП показывать окно с динамически обновляемым индикатором выполнения.

Шаг 3. Обработка результатов завершения операции

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

Проанализируем структуру процедуры обратного вызова на клиенте:


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

&НаСервереБезКонтекста
Функция ПолучитьРезультатИзХранилища(АдресРезультата)
    Возврат ПолучитьИзВременногоХранилища(АдресРезультата);
EndФункции

Важные особенности и технические ограничения

При использовании стандартного механизма прогресс-бара БСП важно помнить о ряде ограничений платформы 1С:

  1. Правило «100 вызовов». Платформа 1С настоятельно рекомендует вызывать метод ДлительныеОперации.СообщитьПрогресс не более 100 раз за весь период работы фонового задания. Слишком частая отправка прогресса (например, на каждой итерации быстрого цикла) приводит к сильной перегрузке сетевого трафика между клиентом и сервером приложений, а также к неоправданному потреблению оперативной памяти. Обязательно рассчитывайте шаг оповещения, как было показано в Шаге 1.
  2. Ограничение транзакций. Вызовы метода СообщитьПрогресс абсолютно не будут работать, если ваш основной цикл выполнения задачи обернут в общую транзакцию базы данных (между операторами НачатьТранзакцию() и ЗафиксироватьТранзакцию()). Платформа физически не сможет передать промежуточные пакеты данных на клиентскую сторону до тех пор, пока транзакция не зафиксируется на сервере.
  3. Минимальный интервал времени (3 секунды). Если фоновое задание вызывает оповещение прогресса чаще одного раза в 3 секунды, платформа может принудительно оптимизировать этот процесс и опускать некоторые промежуточные пакеты данных, чтобы избежать перегрузки интерфейса.
  4. Передача произвольных данных. Третий параметр процедуры ДлительныеОперации.СообщитьПрогресс(Процент, Текст, ДополнительныеПараметры) позволяет передавать на клиент структурированные вспомогательные данные. Они должны быть простыми и сериализуемыми (числа, строки, булево, простые структуры).
  5. Использование во внешних обработках. Если вы разрабатываете внешнюю обработку (например, для справочника "Дополнительные отчеты и обработки"), вы не можете запустить ее метод напрямую через стандартную функцию ВыполнитьПроцедуру. В БСП для этого существует специализированный метод ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки, который берет на себя безопасное выполнение кода внешнего файла в фоне.

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

← На главную