Как реализовать параллельное выполнение задач в 1С:Предприятии 7.7

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

Природа кооперативной многозадачности в 1С 7.7

Прежде всего, проанализируем ситуацию: почему интерфейс системы остается отзывчивым, когда в фоне выполняется тяжелый код? Важно понимать, что в 1С 7.7 нет полноценной многопоточности (multithreading) на уровне ядра системы. То, что мы наблюдаем, называется кооперативной многозадачностью. Платформа работает внутри одного системного потока Windows, но умеет переключать контексты исполнения между различными открытыми окнами и системными сообщениями.

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

Использование немодальных форм для фоновых вычислений

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

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

Посмотрим на пример кода в глобальном модуле, который запускает фоновую выгрузку:


Процедура ПриНачалеРаботыСистемы()
    // Запускаем фоновую обработку немодально
    ОткрытьФорму("Отчет", , КаталогИБ() + "ExtForms\BackgroundExport.ert");
КонецПроцедуры

В самой обработке BackgroundExport.ert мы можем использовать метод Форма.ОбработкаОжидания(), чтобы запускать экспорт порциями, позволяя пользователю работать с другими объектами системы.

Механизм ОбработкаОжидания и системный таймер

Разберем подробнее, как работает ОбработкаОжидания. Этот метод использует системный таймер Windows (WM_TIMER). Особенность заключается в том, что обработчик срабатывает только в те моменты, когда очередь сообщений приложения пуста. Это идеальный инструмент для «фоновой» работы: как только пользователь перестает активно нажимать на кнопки или двигать окна, система выполняет кусок вашего кода.

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


// В модуле формы обработки BackgroundExport.ert
Процедура ВыполнитьПорциюДанных()
    // Здесь идет код обработки части данных
    Состояние("Выполняется фоновая выгрузка...");
    
    // Если работа не закончена, таймер продолжит тикать
    Если ВсеДанныеОбработаны = 1 Тогда
        Форма.ОбработкаОжидания("", 0); // Останавливаем таймер
        Предупреждение("Фоновая выгрузка завершена успешно!");
    КонецЕсли;
КонецПроцедуры

Процедура ПриОткрытии()
    // Запускаем процедуру каждые 2 секунды
    Форма.ОбработкаОжидания("ВыполнитьПорциюДанных", 2);
КонецПроцедуры

Важный нюанс: фоновое выполнение будет приостановлено, если пользователь откроет любое модальное окно или просто зажмет левую кнопку мыши на заголовке окна. Как только блокирующее действие прекратится, выполнение возобновится с того же места.

Синхронизация потоков через глобальные переменные

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

  1. В глобальном модуле объявляем переменную: Перем глРезультатЭкспорта Экспорт;.
  2. В фоновой обработке по завершении расчетов записываем данные в эту переменную.
  3. В основном отчете или журнале проверяем состояние контекста формы или значение флага в глобальной переменной.

Это позволяет, например, запустить формирование сложного отчета в одной форме, продолжать выписывать счета в другой, а когда отчет будет готов — просто забрать результат из глобальной переменной.

Асинхронность через внешние компоненты и COM-объекты

Настоящая асинхронность в 1С 7.7 часто достигается за счет внешних средств. В примере из обсуждения упоминается отправка XML через POST-запрос. Если мы используем объект Microsoft.XMLHTTP, у него есть метод open, третьим параметром которого является флаг асинхронности.

Разберем пример:


HttpОбъект = СоздатьОбъект("Microsoft.XMLHTTP");
// Устанавливаем флаг асинхронности в Истина (1)
HttpОбъект.open("POST", "http://myserver.com/api", 1);
HttpОбъект.send(ДанныеXML);

В этом случае запрос передается системной библиотеке Windows, которая выполняет его в отдельном реальном системном потоке. 1С при этом не ждет ответа и продолжает работу. Для получения результата нам снова понадобится ОбработкаОжидания, которая будет проверять свойство readyState объекта HttpОбъект.

Также стоит упомянуть внешнюю компоненту FormEx. Она расширяет событийную модель 1С 7.7, позволяя перехватывать события клавиатуры и мыши, а также создавать дополнительные цепочки вычислений, которые работают более стабильно, чем стандартные механизмы платформы.

Ограничения и риски «псевдопараллельности»

Несмотря на удобство, использование нескольких параллельных контекстов в «семерке» несет в себе определенные риски, которые мы должны учитывать:

Подводя итог, можно сказать, что 1С 7.7 предоставляет достаточно гибкие (хотя и скрытые) возможности для параллельной работы. Правильное сочетание немодальных форм, метода ОбработкаОжидания и асинхронных COM-объектов позволяет создавать современные и отзывчивые интерфейсы даже на этой почтенной платформе.

← На главную