Асинхронные вызовы свойств и методов Внешних компонент. Особенности 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С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

23.06.2024    7443    bayselonarrend    20    

154

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

13.03.2024    5942    dsdred    16    

80

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

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

24.01.2024    17663    YA_418728146    26    

71

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    11221    dsdred    44    

130

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

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    23756    SeiOkami    48    

135

Механизмы платформы 1С Системный администратор Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    18828    human_new    27    

80

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14729    YA_418728146    7    

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