При разработке инструментов автоматического тестирования или служебных обработок мы часто сталкиваемся с необходимостью программного запуска стандартных отчетов или методов Библиотеки Стандартных Подсистем (БСП). В некоторых сценариях, особенно в файловых базах, нам важно выполнить код синхронно (последовательно), чтобы сразу получить результат, не прибегая к механизму фоновых заданий.
Однако, когда в уравнении появляются расширения конфигурации, поведение системы может показаться нелогичным. Давайте разберем ситуацию, когда мы явно указываем системе «не запускать в фоне», но она игнорирует это требование. Разберемся, почему так происходит и как устроена архитектура платформы в этом аспекте.
Рассмотрим сценарий. У нас есть файловая информационная база с подключенным активным расширением. Наша задача — программно запустить отчет (например, «Проверка внедрения БСП»), но сделать это в «чистой» конфигурации, игнорируя расширение. При этом мы хотим выполнить это действие в текущем потоке (синхронно), а не в фоновом задании.
Мы используем модуль ДлительныеОперации и настраиваем параметры выполнения следующим образом:
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(ИдентификаторФормы);
ПараметрыВыполнения.НаименованиеФоновогоЗадания = НСтр("ru = 'Проверка внедрения БСП'");
// Ключевые параметры конфликта
ПараметрыВыполнения.БезРасширений = Истина; // Хотим "чистую" конфигурацию
ПараметрыВыполнения.СРасширениямиБазыДанных = Ложь;
ПараметрыВыполнения.ЗапуститьНеВФоне = Истина; // Хотим синхронный запуск
РезультатВыполнения = ДлительныеОперации.ВыполнитьФункциюВНесколькоПотоков(ИмяФункции, ПараметрыВыполнения, ПараметрыМетода);
Несмотря на явное указание ЗапуститьНеВФоне = Истина, система все равно инициирует фоновое задание. Если мы заглянем в код модуля ДлительныеОперации, то обнаружим условие, определяющее способ запуска:
ВыполнитьБезФоновогоЗадания = Не ПараметрыВыполнения.БезРасширений
И Не ПараметрыВыполнения.СРасширениямиБазыДанных
И (ОбщегоНазначения.РежимОтладки() Или ПараметрыВыполнения.ЗапуститьНеВФоне ...);
Давайте проанализируем это условие с точки зрения булевой алгебры. Переменная ВыполнитьБезФоновогоЗадания станет Истина только в том случае, если оба флага, касающиеся расширений (БезРасширений и СРасширениямиБазыДанных), равны Ложь.
Если хотя бы один из них установлен в Истина, все выражение обращается в Ложь, и выполнение уходит в ветку фонового задания. Почему разработчики БСП сделали именно так?
Причина такого поведения кроется не в ошибке кода БСП, а в фундаментальном устройстве сеанса пользователя в платформе 1С:Предприятие.
Давайте вспомним важный постулат: Состав метаданных (конфигурация + примененные расширения) фиксируется в момент запуска сеанса и остается неизменным до его завершения.
Это означает, что внутри одного запущенного сеанса (процесса rphost или клиентского приложения) невозможно «временно отключить» расширение, выполнить пару строк кода, а затем «включить» его обратно. Текущий контекст выполнения уже «заражен» активными расширениями.
Когда мы устанавливаем ПараметрыВыполнения.БезРасширений = Истина, мы требуем от системы выполнить код в среде, отличающейся от текущей. Единственный способ для платформы обеспечить среду с другим составом метаданных (без расширений) — это запустить новый сеанс.
Технически БСП реализует это через специальные методы менеджера расширений конфигурации, которые предназначены исключительно для фоновых заданий:
РасширенияКонфигурации.ВыполнитьФоновоеЗаданиеБезРасширений()РасширенияКонфигурации.ВыполнитьФоновоеЗаданиеСРасширениямиБазыДанных()Синхронных аналогов этих методов (например, «ВыполнитьПроцедуруЗдесьИСейчасБезРасширений») в платформе не существует.
Давайте подведем итог нашему расследованию. Приоритет флагов управления расширениями является абсолютным.
БезРасширений = Истина, вы автоматически соглашаетесь на создание нового изолированного сеанса.ЗапуститьНеВФоне игнорируется, так как удовлетворить оба требования одновременно (выполнить в текущем потоке И выполнить без расширений) физически невозможно.Даже в файловой базе фоновое задание представляет собой отдельное соединение (сеанс), что позволяет платформе загрузить для него «чистую» конфигурацию без влияния расширений.
Если вам необходимо отладить этот процесс синхронно, не прибегая к фоновым заданиям, есть только один путь:
Вам необходимо запустить само клиентское приложение (Конфигуратор или Предприятие), в котором вы проводите отладку, с ключом командной строки /NoExtensions.
В этом случае ваш текущий сеанс уже будет работать без расширений. Тогда в коде вызова БСП можно будет не устанавливать флаг БезРасширений = Истина (так как среда и так чистая), и тогда параметр ЗапуститьНеВФоне = Истина сработает штатно, позволив выполнить код в текущем потоке.