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