Начиная с версии платформы 8.3.18, в 1С появился новый синтаксис для работы с асинхронными вызовами — ключевые слова Асинх и Ждать. Многие разработчики по аналогии с другими языками программирования предполагают, что простое добавление модификатора Асинх перед функцией и ее вызов на клиенте автоматически переведет выполнение в фон и избавит пользовательский интерфейс от зависаний. Разберем по шагам, почему это не так, и проанализируем, как на самом деле работает этот механизм.
Рассмотрим пример кода, в котором разработчик пытается найти "числа Армстронга" с помощью серверной функции, вызывая ее в цикле на клиенте:
&НаСервере
Функция ЧислоАрмстронгаСервер(вхЛимит)
библиотека = РеквизитФормыВЗначение("Объект");
возврат библиотека.ЧислоАрмстронга(вхЛимит)
КонецФункции
//Это описание асинхронной функции
&НаКлиенте Асинх
Функция НайтиЧислаАрмстронга(вхЛимит)
возврат ЧислоАрмстронгаСервер(вхЛимит);
КонецФункции
// Вызывается при нажатии кнопки на форме
&НаКлиенте
Процедура РешитьЗадание(Команда)
Для i = 2 до 8 цикл
r = НайтиЧислаАрмстронга(i);
КонецЦикла;
КонецПроцедуры
При выполнении этого кода интерфейс пользователя полностью блокируется. Выясним причину такого поведения. Дело в том, что асинхронные вызовы с модификатором Асинх сами по себе не прерывают выполнение основного потока кода и не создают отдельный физический поток выполнения. Обычные вызовы сервера из клиентского кода в 1С по своей природе являются синхронными. Вызов серверной процедуры всегда блокирует клиентское приложение до получения ответа от сервера.
Даже если обернуть этот вызов в функцию Асинх, платформа просто выполнит синхронный серверный вызов, упакует его результат в специальный объект платформы и вернет на клиент. А поскольку всё это происходит внутри цикла, интерфейс гарантированно "зависнет" до окончания всех итераций.
Новый синтаксис 1С является аналогом паттерна async/await, который применяется в C# или JavaScript. Главная цель этого нововведения — избавить разработчиков от сложного и трудночитаемого кода с использованием ОписаниеОповещения ("ада коллбэков"). Теперь асинхронный код выглядит как обычный последовательный. Посмотрим на три главных элемента этого механизма:
Обещание. Само по себе это слово не делает код магическим образом фоновым.Правильное использование оператора Ждать внутри асинхронной функции выглядит следующим образом:
&НаКлиенте Асинх
Функция НайтиЧислаАрмстронга(вхЛимит)
ПолучаемоеЧисло = Ждать ЧислоАрмстронгаСервер(вхЛимит); // Здесь интерфейс освобождается до получения ответа
Возврат ПолучаемоеЧисло;
КонецФункции
Синтаксис Асинх и Ждать предназначен в первую очередь для работы с готовыми асинхронными методами самой платформы 1С. Начиная с 8.3.18, фирма 1С добавила методы-аналоги с суффиксом "Асинх" (например, ВопросАсинх, КопироватьФайлАсинх), которые действительно выполняются асинхронно и не блокируют интерфейс.
Если перед вами стоит задача выполнить тяжелые вычисления на сервере (например, длительные расчеты, поиск простых чисел, обработка больших объемов данных) и при этом сохранить отзывчивость пользовательского интерфейса, механизм Асинх вам не поможет.
Для этих целей по-прежнему необходимо использовать Фоновые задания. Рассмотрим правильный алгоритм действий:
ФоновыеЗадания.Выполнить запустите серверную процедуру в отдельном фоновом потоке.ПодключитьОбработчикОжидания), который будет периодически, например раз в 2 секунды, проверять статус запущенного фонового задания.Разберем подробнее некоторые особенности работы с новыми асинхронными методами, о которых важно помнить:
Асинх возникает программная ошибка, платформа не выдает привычное окно с красным крестиком немедленно. Ошибка "упаковывается" в возвращаемое Обещание. Чтобы корректно перехватить и обработать такую ошибку, вызов оператора Ждать необходимо оборачивать в конструкцию Попытка ... Исключение.ОбработкаВыбора или ПередЗакрытием платформа ожидает мгновенного возврата параметра Отказ. Использование оператора Ждать внутри таких процедур может привести к непредсказуемому поведению системы или прерыванию стандартной цепочки событий. Для таких случаев 1С добавляет новые специализированные события (например, ПередЗакрытиемАсинх).Таким образом, новые инструменты 1С делают написание клиентского кода удобнее, избавляя от разрозненных процедур-обработчиков оповещений. Но для параллельных серверных вычислений использование механизма фоновых заданий остается единственным верным решением. Для реализации такого подхода можно использовать готовый пример запуска длительных операций через фоновые задания без БСП.