При реализации механизмов обмена данными, особенно между разными версиями платформ (например, при загрузке данных из 1С 7.7 в 1С 8.3), разработчики часто сталкиваются с проблемой «замирания» программы. Пользователь не может нажать ни одну кнопку, окно не перерисовывается, а система кажется зависшей до тех пор, пока процесс обмена не завершится. Проанализируем, почему это происходит при использовании метода ПодключитьОбработчикОжидания, и разберем по шагам, как перевести такие задачи на рельсы регламентных заданий без ущерба для комфортной работы пользователей.
Рассмотрим природу работы этого метода. Метод ПодключитьОбработчикОжидания предназначен для периодического вызова процедуры в контексте клиентского приложения. Это означает, что процедура выполняется в том же самом программном потоке, который отвечает за отрисовку форм, реакцию на нажатия клавиш и движение мыши.
Если процедура обмена выполняется длительное время (например, более 1-2 секунд), основной поток интерфейса блокируется. Пока код обмена не будет выполнен до конца, 1С не сможет обработать ни одно событие интерфейса. Выясним причину: синхронность выполнения. Для длительных операций, таких как COM-соединение с другой базой или обработка тяжелых XML-файлов, этот метод категорически не подходит, так как он делает работу пользователя в программе невозможной на время обмена.
Для того чтобы интерфейс оставался отзывчивым, необходимо вынести тяжелые вычисления в отдельный поток. В платформе «1С:Предприятие 8.3» для этого предусмотрен механизм фоновых и регламентных заданий. Рассмотрим, как правильно настроить их в файловом варианте базы данных, где нет сервера приложений, который бы управлял очередью заданий самостоятельно.
В файловой базе регламентные задания требуют особого подхода. Проанализируем основные требования для их работы:
Для создания регламентного задания в конфигураторе нам потребуется выполнить следующие действия:
РегламентноеЗадание.ИмяМетода — процедуру в общем модуле, которая будет выполнять обмен.Использование и Предопределенное.Расписание (например, каждые 120 секунд).Когда мы переносим код из обычной обработки в модуль, вызываемый регламентным заданием, мы попадаем в условия серверного контекста (даже в файловой базе). Проанализируем критические ограничения, из-за которых код может «вылетать» с ошибкой:
1. Полный запрет интерактивности. Фоновое задание выполняется без участия человека, у него нет окна. Поэтому использование любых методов, требующих взаимодействия с пользователем, приведет к аварийному завершению задания. Рассмотрим список запрещенных методов:
Предупреждение() — вызывает ошибку исполнения.Вопрос() — не может быть задан в фоновом режиме.Состояние() — метод вывода текста в статус-бар клиента недоступен на сервере.ОткрытьФорму() — сервер не может открывать визуальные окна.2. Метод Сообщить(). Важно понимать, что Сообщить() в фоновом задании не вызывает ошибку, но и пользы не приносит: пользователь не увидит этих сообщений. Все оповещения о ходе обмена нужно записывать в журнал регистрации.
3. Глобальные переменные. Переменные, объявленные в модуле управляемого или обычного приложения через ключевое слово Экспорт, в фоновом задании недоступны. Фоновое задание инициализирует свой собственный контекст. Разберем пример: если вы хранили путь к базе 7.7 в глобальной переменной на клиенте, серверный код ее не увидит. Рекомендуется использовать константы или параметры сеанса для хранения таких данных.
Посмотрим на пример правильной организации кода для фонового обмена:
Процедура ВыполнитьОбменДанными() Экспорт
Попытка
// Вместо Состояние() используем запись в Журнал регистрации
ЗаписьЖурналаРегистрации("ОбменДанными", УровеньЖурналаРегистрации.Информация, , , "Начало выполнения обмена...");
// Код подключения к 1С 7.7 или другой системе
// ... (ваш код обмена)
ЗаписьЖурналаРегистрации("ОбменДанными", УровеньЖурналаРегистрации.Информация, , , "Обмен успешно завершен.");
Исключение
// Обязательно ловим ошибки, иначе задание просто молча упадет
ТекстОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации("ОбменДанными", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка при обмене: " + ТекстОшибки);
КонецПопытки;
КонецПроцедуры
Одна из главных трудностей, с которой столкнулся автор темы — отладчик не «заходит» в код регламентного задания. Выясним, как заставить отладку работать. По умолчанию отладчик подключен только к текущему клиентскому сеансу. Чтобы поймать фоновое задание, выполним следующие шаги:
Теперь при срабатывании расписания платформа автоматически подключит отладчик к новому процессу фонового задания, и ваша точка останова сработает.
Если ваш обмен завязан на подключение к 1С 7.7 через COM, проанализируем еще одну тонкость. Платформа 1С 7.7 является строго 32-битным приложением. Если ваше регламентное задание запускается на 64-битной платформе 1С 8.3 (в клиент-серверном варианте), прямой вызов Новый COMОбъект("V77.Application") может завершиться ошибкой «Класс не зарегистрирован».
В файловом варианте, если вы запускаете сеанс 32-битным клиентом, этой проблемы не возникнет. Однако при переходе на сервер стоит об этом помнить и использовать либо 32-битный сервер 1С, либо настраивать компонент COM+ в Windows для проксирования вызовов между 64-битным процессом 1С и 32-битным COM-объектом седьмой версии.
Подводя итог, отметим: использование ПодключитьОбработчикОжидания допустимо только для очень быстрых операций (проверка почты, проверка новых сообщений), которые длятся доли секунды. Для полноценного обмена данными всегда выбирайте Регламентные задания, соблюдая правила «тишины» (отсутствие интерактивных методов) и автономности контекста.