Асинхронные вызовы свойств и методов Внешних компонент. Особенности 2-х способов асинхронной работы

28.03.23

Разработка - Механизмы платформы 1С

Подсказка по использованию асинхронных вызовов и методов Внешних компонент. Есть ли отличия асинхронных вызовов от обычных для компоненты. Отличия "Обратного вызова" от вызова через "Обещания". Ответ на вопрос: Асинхронность и Параллельность - одно и то же?

Полный синтаксис вызовов методов, получения и установки свойств:


В документации 1С на странице https://its.1c.ru/db/v8321doc#bookmark:dev:TI000001509 описан синтаксис асинхронной работы с компонентами, но тестируя свою компоненту, мне пришлось опытным путем выявлять, какие параметры используются при получении, установке свойства и вызове метода, в основном в первом варианте работы с помощью обратного вызова. Дело в том, что у Вас может стоять далеко не последний релиз версии 8.3, а способ вызова через Обещания появился лишь начиная с 18 релиза этой версии платформы. Итак:
 

  1. Перед Асинхронным вызовом, любым, создаем Оповещение объект типа ОписаниеОповещения, конструктор Оповещения описан в Синтакс-помощнике, но там не совсем четко указано, что стоит, а что нет заполнять.
    1. Пример правильного заполнения для варианта Получения свойства:
      Оповещение=Новый ОписаниеОповещения("ОбработкаЧтенияСвойства",ЭтаФорма,ПараметрыСвойства,"ОбработкаАсинхронногоВызоваОшибка",ЭтаФорма);

      Где:

      1. ОбработкаЧтенияСвойства - процедура обратного вызова, при получении результата свойства. Имеет такой синтаксис 

        &НаКлиенте
        Процедура ОбработкаЧтенияСвойства(Значение,ПараметрыСвойства) Экспорт
        КонецПроцедуры
        

        Где:

        1. Значение - переменная с результатом чтения свойства.

        2. ПараметрыСвойства - структура, в которой мы можем получить, например ИмяСвойства, которое было передано перед созданием ОписанияОповещения, например: 

          ПараметрыСвойства=Новый Структура("Ключ",ИмяСвойства);
      2. ЭтаФорма - контекст, в котором находится обработчик (текущая форма)
      3. ПараметрыСвойства - Структура, в которой можно передать Ключ и другие параметры, необходимые для обработки полученного свойства.
      4. ОбработкаАсинхронногоВызоваОшибка - процедура обратного вызова, если сгенерировано исключение или отказ компоненты на запрос по получению/установке свойства, или вызову метода. Она может быть одна для всех вызовов, синтаксис обработчика следующий: 
        &НаКлиенте
        Процедура ОбработкаАсинхронногоВызоваОшибка(Знач ИнформацияОбОшибке, СтандартнаяОбработка = Истина, ДополнительныеПараметры = Неопределено) Экспорт
        	СтандартнаяОбработка=Ложь;
        КонецПроцедуры
        

        Где:

        1. ИнформацияОбОшибке - объект с типом ИнформацияОбОшибке, который содержит информацию об ошибке.

        2. СтандартнаяОбработка - если мы сами хотим обработать исключение, то должна быть установлена в Ложь.

        3. ДополнительныеПараметры - структура с дополнительными параметрами при ошибке.

      5. ЭтаФорма - то же самое, контекст, в котором обработчик ошибок находится.

    2. Пример Оповещения при установке Свойства:

      Оповещение=Новый ОписаниеОповещения("ОбработкаУстановкиСвойства",ЭтаФорма,ПараметрыСвойства,"ОбработкаАсинхронногоВызоваОшибка",ЭтаФорма);
      

      Отличия от предыдущего описания в том, что данный обработчик установки свойства имеет такой синтаксис:

      Процедура ОбработкаУстановкиСвойства(ПараметрыСвойства) Экспорт
      КонецПроцедуры
      

      Где в ПараметрыСвойства мы можем получить как имя свойства, так и его значение, которое передавалось, если озаботились передачей сих ранее.

    3. Пример Оповещения перед вызовов методов компоненты: 

      Оповещение=Новый ОписаниеОповещения("ОбработкаВыполненияМетода",ЭтаФорма,ПараметрыМетода,"ОбработкаАсинхронногоВызоваОшибка",ЭтаФорма);

      Где:

      1. ОбработкаВыполненияМетода - имя процедуры-обработчика обратного вызова. Имеет следующий синтаксис: 

        &НаКлиенте
        Процедура ОбработкаВыполненияМетода(РезультатМетода,ПараметрыМетода,ДополнительныеПараметры) Экспорт
        КонецПроцедуры
        

        Где:

        1. РезультатМетода - произвольного типа, значение, которое возвращается методом компоненты, если он возвращает значение.

        2. ПараметрыМетода - параметры метода, которые были переданы в компоненту. Возможно часть параметров, может быть изменены самой компонентой.

        3. ДополнительныеПараметры - структура дополнительных параметров, что была передана асинхронным вызовом метода.

      2. ЭтаФорма - контекст, в котором находится обработчик (текущая форма)
      3. ПараметрыМетода - Структура, в которой можно передать Имя метода и другие параметры, необходимые для обработки результата вызова метода.
      4. ОбработкаАсинхронногоВызоваОшибка - обработчик исключений компоненты. Синтаксис уже описан.

      5. ЭтаФорма - то же самое, контекст, в котором обработчик ошибок находится.

  2. Получение/передача значения свойства и выполнение методов компоненты способом "Обратного вызова" уже описаны  в документации, я просто их перечислю в правильном синтаксисе:

    1. Аддон.НачатьПолучение<ИмяСвойства>(Оповещение)

    2. Аддон.НачатьУстановку<ИмяСвойства>(Оповещение,Значение)

    3. Для вызовов методов без параметров: Аддон.НачатьВызов<ИмяМетода>(Оповещение)

    4. Для вызовов методов с параметрами: Аддон.НачатьВызов<ИмяМетода>(Оповещение,Параметр1,...)

  3. Получение/передача значения свойства и выполнение методов компоненты через Обещание также уже описаны  в документации. Следует отметить, что все процедуры и функции, содержащие эти инструкции, должны быть обозначены оператором Асинх перед названием процедуры и функции 1С. Перечислим:

    1. Получение свойства: 
      Значение=Ждать Аддон.Получить<ИмяСвойства>Асинх();
    2. Установка свойства: 

      Результат=Ждать Аддон.Установить<ИмяСвойства>Асинх(Значение);
    3. Выполнение метода компоненты: 

      Значение=Ждать Аддон.<ИмяМетода>Асинх(); // функция без параметров, возвращает тип "РезультатАсинхВызоваВнешнейКомпоненты"
      Ждать Аддон.<ИмяМетода>Асинх(); // процедура без параметров
      Значение=Ждать Аддон.<ИмяМетода>Асинх(ЗначениеПараметра1,...); // функция с явным перечислением параметров, возвращает "РезультатАсинхВызоваВнешнейКомпоненты"

       

Особенности использования асинхронных вызовов свойств и методов внешних компонент:

 

  1. Отличия взаимодействия 1С с компонентой в режиме синхронной и асинхронной работы. Отличия в работе асинхронного режима от синхронного все-таки есть. Они проявляются в кешировании имени свойства на стороне 1С при асинхронных вызовах. Т.е. при обычной работе с компонентой, прежде чем получить или установить Значение по имени свойства, 1С всегда выполняет метод компоненты FindProp. Это позволяет использовать динамический набор свойств в случае, если компонента этого хочет. Например, в одном из случаев реализации моей компоненты, есть метод Сортировать (Sort), который сортирует свойства по имени. Т.е. порядок Свойств может поменяться. И для обычных вызовов это приемлемо и позволяет осуществлять определенную гибкость в реализации. В асинхронных вызовах получения/установки свойств - если свойство хотя бы раз уже было получено, то 1С сразу выполняет методы GetValue или SetValue с заранее полученными номерами этих свойств. Зачем это сделано, я не знаю, но может привести к серьезным проблемам, когда вы ждете одно свойство, а получаете или устанавливаете другое... Поэтому для компонент, динамически меняющих состав свойств - асинхронные вызовы не рекомендуются. То же касается и методов FindMethod. Только мне сложно представить, что кто-то будет реализовывать динамический набор методов, но лично я реализовывал разные наборы методов в зависимости от того, какой вложенный в компоненте объект использовался. Но остановился на том, что номера методов лучше не менять ни в каком режиме. 
  2. Рассмотрим поведение 1С при разных вариантах реализации Асинхронных вызовов. Что я выявил:
    1. Все знают, что неудобно разрабатывать в режиме "Обратного вызова" проекты, из-за загромождения лишними функциями (Callback) и операторами создания Оповещений. Но, оказывается, так все же надежнее и гибче эти методы выполняются.
      1. Во первых в режиме Модальности - или для УФ - это будет по факту режим блокирования родительского окна, после того как мы запустим функцию работы компонентой в режиме "обратного вызова", она сразу начнется исполняться, не дожидаясь выхода и закрытия модального окна. Это выявлено как в УФ, так и в обычных формах.
      2. Во вторых, мы можем динамически формировать код, который хотим выполнить, если мы заранее не знаем, какое свойство или метод мы будем выполнять и используем операторы Выполнить или Вычислить.
    2. Способ работы со свойствами и методами компонент в режиме формирования Обещаний, соблазнителен на первый взгляд из-за краткости написания кода, но имеет недостатки:
      1. В модальных вызовах форм (путем блокировки родительского окна для УФ), все методы и свойства компонент, вызываемые через обещания с помощью оператора Ждать, не начнут выполняться, пока не закроется модальное окно и не освободит родительское для принятия оконных сообщений.
      2. Мы через обещания можем работать только с явно заданными свойствами и методами внешних компонент. Т.е. не работают операторы Выполнить и Вычислить, что ограничивает разработчика в некоторых действиях, например, когда нам нужно протестировать работу неизвестной компоненты в автоматическом режиме. Или мы не можем делать код, в котором должна будет на место драйвера подгружаться пока неизвестная нам компонента с неизвестными свойствами.

 

Асинхронность и параллельность, то ли мы купили:

 

Когда мы слышим Асинхронность, мы не всегда понимаем, что стоит за этим словом и как это работает в системе. Многие считают, что это освобождает Основной поток и дает параллельность в выполнении задач. На самом деле это не так, это не имеет никакого отношения к реальной поточной работе. Реальный параллелизм возникает, когда мы запускаем какое-то задание в Фоновом процессе на Сервере. Там оно выполняется в отдельной среде без выделения ему ресурсов как для отдельной задачи, но по факту это задача со своей таблицей управления и набором регистров. Система переключает не только процессы, но и потоки между процессами, выделяя каждому определенные кванты времени, переключаясь между ними, обеспечивая баланс между переключениями меж самих процессов и между потоками этого процесса. И в целом эти все потоки  выполняются почти параллельно. Но есть в системе старый способ обеспечивать параллельность в работе, который пришел к нам из Windows 3.0, с помощью эмуляции параллелизма через очередь сообщений в Главные окна. Принцип работы заключается в том, что система выполняет какое-то задание через очередь сообщений и затем после возвращает управление системе, ожидая следующего задания. Так это работает и сейчас для взаимодействия с пользователем через GUI в окнах. Асинхронный режим, который реализуется в 1С, тоже использует очередь сообщений. Когда мы запускаем задание через асинхронную функцию, платформа 1С создает для неё обработчик и либо сразу запускает его, либо после того, как обработает текущее сообщение окна. Мы же получаем эмуляцию многопоточного режима, она работает успешно на оконных, диалоговых и файловых операциях, за счет того, что данные операции способны освобождать ресурсы и передавать управление главному окну в ожидании оконных сообщений. Поэтому асинхронные операции в основном используются в таких операциях, как Предупреждение, Вопрос, Диалог выбора файла, загрузок файлов и т.д.

Что касается конкретно компонент: не думаю, что в большинстве случаев это уместно, но есть длительные операции по загрузке больших изображений, обработке их, работе с торговым и другим оборудованием, которые тоже освобождают свои ресурсы для главного окна программы, и тогда они действительно полезны. В результате того, какой метод "Обратного вызова" или через Обещание используется, мы имеем приоритет начала выполнения операции, которой вызываем асинхронную функцию. В старом варианте она вызывается сразу, а затем управление передается текущему окну, а в новом через Обещание, операция передается после обработки текущего оконного сообщения, как я предполагаю главного окна программы. Отсюда и выходит, что пока мы не выйдем из Модального диалога, новая операция через Ожидание - не начнется...

 

Резюме:

 

Чтобы компонента была совместима с асинхронными операциями, и могла бы использоваться в браузерах, которые требуют исключительно асинхронных операций, то она должна иметь статический набор свойств и методов, которые не меняют ни состав, ни порядок свойств, и нумерация методов не должна меняться.

Если компонента не рассчитана на использование браузеров, то асинхронные операции лучше использовать только на действительно длительных операциях, таких как, например, Эквайринг, загрузка и выгрузка фото и видео-контента, и других, связанных с файловым обменом, а также диалоговых окнах, если таковые присутствуют. В обычных случаях, лучше избегать использования асинхронных операций.

В способе "Обратного вызова" - не ленитесь передавать маркеры как минимум названия свойства или метода в объект Оповещение. А также создайте и передавайте процедуру обработки исключений, тогда Вы точно будете знать, на какой операции у Вас оно произошло. Эта процедура может быть одна на текущий модуль или находиться в Общем модуле.

 

На этом пока все, буду рад, если кому-то это покажется полезным.

Вступайте в нашу телеграмм-группу Инфостарт

Асинх Компонента

См. также

Механизмы платформы 1С Программист Бесплатно (free)

Разберем 15 мифов о работе платформы «1С:Предприятие 8» – как распространенных, так и малоизвестных. Начнем с классики: «Код, написанный в одну строку, работает быстрее, чем многострочный». Так ли это на самом деле?

16.07.2025    26303    TitanLuchs    106    

145

Механизмы платформы 1С Работа с интерфейсом Программист Стажер 1С:Предприятие 8 Бесплатно (free)

Про ООП в 1С и о том, как сделать свой код более кратким и выразительным при помощи использования текучего интерфейса (fluent interface).

03.02.2025    14564    bayselonarrend    127    

68

Механизмы платформы 1С Программист 1С:Предприятие 8 Бесплатно (free)

В этой статье подробно рассматривается работа с JSON в XDTO в 1С:Предприятие. Вы узнаете, как сериализовать и десериализовать объекты XDTO в JSON, интегрировать 1С с веб-сервисами и API, а также корректно обрабатывать данные при обмене. Разбираются особенности работы с коллекциями, использование функций восстановления и частые ошибки при работе с JSON и XDTO.

30.01.2025    16025    user2122906    9    

60

Механизмы платформы 1С WEB-интеграция Программист 1С:Предприятие 8 Бесплатно (free)

В платформе 8.3.27 появилась возможность использовать WebSocket-клиент. Давайте посмотрим, как это все устроено и чем оно нам полезно.

14.01.2025    26497    dsdred    77    

142

Механизмы платформы 1С Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    24428    bayselonarrend    22    

175

Механизмы платформы 1С Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    13447    dsdred    22    

85
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. SerVer1C 998 28.03.23 11:06 Сейчас в теме
Хорошо, что 1С разрешает использовать одну и ту же компоненту и в синхронных вызовах (Аддон.<ИмяМетода>()), и в асинхронных с платформы 18+ (Ждать Аддон.<ИмяМетода>Асинх()), не пересобирая её.
2. ksuman 24 29.03.23 02:45 Сейчас в теме
(1) Работать она будет, вопрос в том, будет ли компонента на длительных операциях использовать свои встроенные асинхронные подоперации для того чтобы сделать реальную работу в асинхронном режиме, или это останется имитацией асинхронного режима - на совести разработчика компоненты.
3. user690463_mike124 05.01.26 18:42 Сейчас в теме
(1) В документации написано, что пересобирать, как раз, надо. Но изменять ничего не надо.
4. user690463_mike124 05.01.26 18:50 Сейчас в теме
Тут у меня остро встал вопрос по асинхронному вызову методов ВК. Прочитал статью, но так и не понял, куда надо прикрутить эти ОписаниеОповещения, которые так хорошо расписаны в начале статьи.

Сделал через обещание, как в документации. Потом открыл БПО, а там тоже драйвера используются асинхронно через обещание.

И еще, важно, может кому понадобится: если нативную компоненту подключать изолированно, то она не сможет передавать события платформе. Т.е. на вызов ExternalEvent изнутри компоненты платформа никак не отреагирует. Судя по всему, достигается абсолютная изоляция от всех событий ВК, как исключений, так и специально сгенерированных.
5. user690463_mike124 05.01.26 19:40 Сейчас в теме
Упустил важный момент. Нативные компоненты при отладке надо подключать не изолированно, иначе отладчик просто не получит отклик от отлаживаемой компоненты.
Я отлаживался в Visual Studio, в параметрах проекта, в отладке, указано запускать клиент 1С.
Для отправки сообщения требуется регистрация/авторизация