Как реализовать выполнение длительных операций в фоновом режиме в 1С 8.3?

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

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

Зачем нужны фоновые задания и как они работают

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

Выясним причину, по которой нельзя просто вызвать серверную процедуру. Обычный вызов &НаСервере заставляет клиентское приложение ждать ответа. Механизм фоновых заданий использует объект ФоновыеЗаданияМенеджер, который инициирует новый процесс на сервере приложений 1С.

Пошаговая инструкция по запуску фонового задания

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


// Процедура на клиенте для запуска процесса
&НаКлиенте
Процедура ЗапуститьДлительнуюОперацию()
    
    ПараметрыЗадания = Новый Массив;
    ПараметрыЗадания.Добавить(Параметр1);
    ПараметрыЗадания.Добавить(Параметр2);
    
    // Запускаем фоновое задание на сервере
    РезультатЗапуска = ЗапуститьЗаданиеНаСервере(ПараметрыЗадания);
    
    // Настраиваем обработчик ожидания для проверки статуса
    ПодключитьОбработчикОжидания("ПроверитьСтатусЗадания", 2);
    
КонецПроцедуры

Разберем, что происходит в этом фрагменте. Мы упаковываем все необходимые данные в Массив и вызываем серверную функцию, которая создаст задание. После этого мы используем метод ПодключитьОбработчикОжидания, чтобы периодически спрашивать сервер: «Готов ли результат?».

Программная реализация на стороне сервера

Посмотрим на пример серверной функции, которая непосредственно создает объект ФоновоеЗадание. Нам потребуется метод Выполнить менеджера фоновых заданий.


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

В данном примере ДлительныеОперацииСервер.ВыполнитьРасчет — это путь к вашей процедуре, которая будет выполнять полезную работу. Обратите внимание на использование УникальныйИдентификатор. Это позволяет нам в дальнейшем однозначно идентифицировать конкретное задание среди множества других.

Мониторинг состояния и получение результата

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


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

Для получения статуса на сервере мы используем метод НайтиПоУникальномуИдентификатору. Важно обрабатывать различные состояния объекта СостояниеФоновогоЗадания, такие как Активно, Завершено, ЗавершеноСОшибкой или Отменено.

Особенности работы в файловом и клиент-серверном вариантах

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

Важные ограничения при разработке фоновых заданий

Рассмотрим подробнее ограничения, о которых часто забывают начинающие разработчики:

  1. Отсутствие пользовательского интерфейса: В фоновом задании нельзя использовать модальные окна, вызывать Предупреждение, Вопрос или обращаться к объектам типа Форма. Весь программный код должен быть строго серверным.
  2. Контекст выполнения: Фоновое задание запускается в новом сеансе. Это значит, что параметры сеанса могут быть не инициализированы, если не прописана соответствующая логика в модуле сеанса.
  3. Передача параметров: Данные, передаваемые в фоновое задание, должны быть сериализуемыми. Нельзя передать ссылку на объект, который существует только в памяти текущего сеанса (например, открытую форму).
  4. Транзакции: Каждое фоновое задание выполняется в своей собственной транзакции. Если основная транзакция на клиенте откатится, фоновое задание об этом «не узнает» и продолжит работу, если оно уже было инициировано.

Обработка ошибок и отладка

Как отладить код, который выполняется «где-то там» на сервере? Проанализируем инструменты отладки. В конфигураторе необходимо включить «Отладку фоновых заданий» в меню «Отладка – Настройка». После этого точки останова в общем модуле будут срабатывать, когда фоновый процесс дойдет до соответствующей строки кода.

Для обработки исключительных ситуаций внутри самого задания обязательно используйте конструкцию Попытка...Исключение. Рассмотрим пример:


Процедура ВыполнитьРасчет(Параметры) Экспорт
    Попытка
        // Основная логика
        ЗаписатьРезультатыВРегистр(Параметры);
    Исключение
        // Запись ошибки в журнал регистрации для администратора
        ЗаписьЖурналаРегистрации("ФоновоеЗадание.Ошибка",
            УровеньЖурналаРегистрации.Ошибка, , ,
            ПодробноеОписаниеОшибки(ИнформацияОбОшибке()));
        ВызватьИсключение; // Пробрасываем ошибку выше, чтобы статус задания стал "Ошибка"
    КонецПопытки;
КонецПроцедуры

Использование ЗаписьЖурналаРегистрации является критически важным, так как это единственный надежный способ узнать детали падения процесса, если интерактивный сеанс уже закрыт.

Рекомендации по использованию БСП

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

  1. Функция ДлительныеОперации.ЗапуститьВыполнениеНаСервере() — автоматически создает задание и возвращает структуру с идентификатором.
  2. Готовые формы ожидания с индикаторами прогресса (ProgressBar).
  3. Автоматическая очистка завершенных заданий из памяти сервера.

Посмотрим на пример использования БСП:


ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
ПараметрыВыполнения.НаименованиеФоновогоЗадания = "МояДлительнаяЗадача";

Результат = ДлительныеОперации.ВыполнитьВФоне("МойОбщийМодуль.МояПроцедура", 
                                              ПараметрыПроцедуры, 
                                              ПараметрыВыполнения);

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

← На главную