Почему механизмы Асинх и Ждать в 1С не дают параллельности и как они работают на самом деле?

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

Разработчики, переходящие на современные версии платформы «1С:Предприятие 8.3» (начиная с 8.3.18), часто сталкиваются с обманчивым ощущением, что ключевые слова Асинх и Ждать привносят в систему полноценную многопоточность, аналогичную C# или Java. Однако при попытке выполнить тяжелые расчеты в «параллельном» режиме выясняется, что код все равно выполняется последовательно, а интерфейс замирает. Проанализируем, почему так происходит, и разберем истинное назначение асинхронности в 1С.

Разбор типичной ошибки: почему цикл не стал параллельным

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


&НаКлиенте
Асинх Процедура ВыполнитьРасчет(Команда)
    
    Обещание1 = ТяжелыйСчет(5); // Запуск первой функции
    Обещание2 = ТяжелыйСчет(5); // Запуск второй функции
    
    Результат1 = Ждать Обещание1;
    Результат2 = Ждать Обещание2;
    
КонецПроцедуры

&НаКлиенте
Асинх Функция ТяжелыйСчет(Множ)
    М = 0;
    Для Й = 1 по Множ * 1000000 Цикл
        М = Й;
    КонецЦикла;
    Возврат Строка(ТекущаяДата());
КонецФункции

В данном примере параллельности не будет. Выясним причину: в 1С клиентское приложение работает в одном основном потоке. Когда вызывается первая функция ТяжелыйСчет, управление передается в неё. Поскольку внутри функции находится обычный цикл Для, он полностью захватывает этот единственный поток. Пока цикл не завершится, управление не вернется в вызывающую процедуру, и вторая функция даже не начнет выполняться. Платформа 1С использует модель асинхронности, схожую с NodeJS: событийно-ориентированный цикл в одном потоке.

Асинхронность vs Параллельность: в чем разница?

Важно четко разделять эти понятия, чтобы эффективно проектировать систему. Рассмотрим основные отличия:

  1. Асинхронность — это способ организации кода, при котором выполнение задачи может быть приостановлено (без блокировки потока) для ожидания какого-либо внешнего события. В это время поток может заниматься чем-то другим (например, перерисовывать интерфейс).
  2. Параллельность — это одновременное выполнение нескольких задач в разных потоках процессора или на разных ядрах.

В 1С конструкции Асинх и Ждать реализуют именно асинхронность. Они предназначены для I/O-bound операций (операций ввода-вывода), где процессор большую часть времени просто ждет ответа от внешнего ресурса:

Если же вы поместите в асинхронную функцию CPU-bound задачу (математические расчеты, обработка больших массивов данных в цикле), она все равно будет выполняться синхронно и блокировать поток, так как процессору некогда «переключаться» — он занят вычислениями.

Как работает объект «Обещание» (Promise)

Проанализируем ситуацию с точки зрения типов данных. Любая функция, помеченная как Асинх, всегда возвращает специальный объект — Обещание (Promise). Это своего рода «квитанция» на получение результата в будущем.

Посмотрим на пример из кода выше:

Обещание1 = ТяжелыйСчет(5);

Здесь переменная Обещание1 содержит не строку с датой, а объект типа Обещание. Когда мы пишем Ждать Обещание1, мы говорим платформе: «Приостанови выполнение этой процедуры, освободи поток для других задач и вернись сюда только тогда, когда это обещание будет выполнено».

Реальное применение: как сделать интерфейс отзывчивым

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


&НаКлиенте
Асинх Процедура ОформитьЗаказ(Команда)
    
    Ответ = Ждать ВопросАсинх("Продолжить оформление?", РежимДиалогаВопрос.ДаНет);
    Если Ответ <> КодВозвратаДиалога.Да Тогда
        Возврат;
    КонецЕсли;
    
    Файл = Ждать ПоместитьФайлНаСерверАсинх( , , , УникальныйИдентификатор);
    // Пока файл загружается, интерфейс остается живым
    
КонецПроцедуры

Здесь Ждать действительно приносит пользу: пока пользователь думает над вопросом или пока файл летит на сервер, поток клиента свободен. Пользователь может свернуть окно, нажать другие кнопки (если они не заблокированы логикой), а платформа будет обрабатывать эти события.

Как добиться настоящей параллельности в 1С

Если перед нами стоит задача действительно параллельных вычислений, нам нужно выйти за рамки клиентского потока. Для этого в 1С существуют Фоновые задания. Они выполняются на стороне сервера в отдельных процессах операционной системы.

Схема работы для достижения параллельности должна быть следующей:

  1. Клиент вызывает серверную процедуру.
  2. Сервер запускает несколько фоновых заданий через ФоновыеЗадания.Выполнить().
  3. Каждое фоновое задание выполняется в своем потоке на сервере.
  4. Клиент периодически проверяет состояние заданий или ждет их завершения.

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

Преимущества нового синтаксиса

Несмотря на отсутствие параллельности, Асинх/Ждать — это не просто «синтаксический сахар». Этот механизм значительно упрощает разработку:

Подведем итоги

Выясним главные правила работы с асинхронностью в 1С:

  1. Конструкции Асинх и Ждать работают в одном потоке на клиенте.
  2. Они не ускоряют вычисления, а лишь позволяют потоку не простаивать во время ожидания (ввода-вывода).
  3. Тяжелые циклы и расчеты в асинхронных функциях по-прежнему блокируют интерфейс.
  4. Для настоящей параллельности используйте Фоновые задания на сервере.
  5. Асинхронность — это современная замена модальным окнам и сложным цепочкам ОписаниеОповещения, делающая код чище и стабильнее.
← На главную