Как работать со свойствами внешних компонент 1С в асинхронном режиме

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

При переходе на современную модель разработки в среде 1С:Предприятие 8.3 программисты все чаще сталкиваются с необходимостью отказа от синхронных вызовов. Это связано с требованиями безопасности браузеров в веб-клиенте, особенностями работы мобильных платформ и общим стремлением к повышению отзывчивости интерфейса. Если с методами внешних компонент (ВК), работающих по технологии NativeAPI, все кажется интуитивно понятным (используется префикс НачатьВызов), то работа со свойствами часто вызывает вопросы. Разберем детально, как корректно организовать чтение и запись свойств компоненты в асинхронном коде.

Проблема синхронного доступа к свойствам

В классическом (синхронном) режиме мы обращаемся к свойству внешней компоненты напрямую, как к реквизиту объекта. Проанализируем типичный пример:


// Синхронный подход
Включен = МояКомпонента.Активен; // Чтение свойства
МояКомпонента.Активен = Истина; // Установка свойства

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

Асинхронное получение значения свойства

Выясним, какой механизм предоставляет платформа для чтения данных. Для каждого свойства, объявленного в компоненте, 1С автоматически генерирует метод с префиксом НачатьПолучение. Рассмотрим синтаксис этого вызова:

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

Разберем по шагам процесс реализации на примере гипотетического свойства ВесОбъекта:

  1. Подготовим процедуру обратного вызова (callback), которая будет выполнена, когда компонента вернет значение.
  2. Создадим объект ОписаниеОповещения, указывающий на эту процедуру.
  3. Вызовем метод получения свойства.

Посмотрим на пример кода:


&НаКлиенте
Процедура УзнатьВес()
    Оповещение = Новый ОписаниеОповещения("ПослеПолученияВеса", ЭтотОбъект, "ДополнительныйПараметрКонтекста");
    МояКомпонента.НачатьПолучениеВесОбъекта(Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ПослеПолученияВеса(ЗначениеСвойства, ДополнительныеПараметры) Экспорт
    Если ЗначениеСвойства = Неопределено Тогда
        Сообщить("Не удалось получить значение свойства");
    Иначе
        Сообщить("Текущий вес: " + ЗначениеСвойства);
        Сообщить("Контекст: " + ДополнительныеПараметры);
    КонецЕсли;
КонецПроцедуры

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

Асинхронная установка значения свойства

Аналогичным образом реализуется запись данных в компоненту. Платформа добавляет префикс НачатьУстановку к имени свойства. Рассмотрим структуру вызова:

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

Проанализируем пример установки свойства ЗаголовокОкна:


&НаКлиенте
Процедура УстановитьЗаголовок()
    НовоеЗначение = "Рабочее место оператора";
    Оповещение = Новый ОписаниеОповещения("ПослеУстановкиЗаголовка", ЭтотОбъект);
    
    // Вызываем асинхронную установку
    МояКомпонента.НачатьУстановкуЗаголовокОкна(Оповещение, НовоеЗначение);
КонецПроцедуры

&НаКлиенте
Процедура ПослеУстановкиЗаголовка(ДополнительныеПараметры) Экспорт
    // Здесь нет параметра "Значение", так как мы его устанавливали
    Сообщить("Свойство успешно обновлено в компоненте");
КонецПроцедуры

Обратите внимание, что в процедуре обратного вызова при установке свойства отсутствует параметр со значением — возвращаются только дополнительные параметры контекста. Если при установке в C++ коде компоненты возникнет ошибка (метод SetPropVal вернет false), платформа может инициировать исключение или передать информацию через другие механизмы оповещения в зависимости от реализации.

Механизм генерации асинхронных методов

Многих разработчиков интересует вопрос: нужно ли в коде самой DLL на языке C++ описывать методы НачатьПолучение...? Нет, этого делать не нужно.

Платформа 1С:Предприятие реализует «обертку» (wrapper) над объектом внешней компоненты. Когда вы вызываете НачатьПолучение или НачатьУстановку, платформа перехватывает это обращение. Она самостоятельно создает поток ожидания или использует механизмы событийного цикла (в веб-клиенте), после чего вызывает стандартные методы интерфейса IComponentBase: GetPropVal для чтения и SetPropVal для записи.

Однако для корректной работы этого механизма необходимо соблюдение двух условий:

Особенности работы в различных окружениях

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

  1. Веб-клиент: Современные браузеры (Chrome, Firefox, Safari) работают в многопоточном режиме, где основной поток JavaScript не должен блокироваться. Синхронное обращение к расширению, которое вызывает DLL, технически невозможно без полной заморозки страницы. Платформа 1С в веб-клиенте транслирует асинхронные вызовы в асинхронные сообщения между браузером и расширением.
  2. Мобильная платформа: Здесь требования к отзывчивости интерфейса еще выше. Длительная операция в UI-потоке приведет к тому, что операционная система предложит пользователю закрыть "зависшее" приложение. Использование Начать... методов позволяет избежать блокировки интерфейса.
  3. Тонкий клиент: Даже если синхронные вызовы разрешены, использование асинхронных методов защищает ваше приложение от "фризов" при выполнении тяжелых операций внутри компоненты (например, при обращении к оборудованию или сложной математике).

Советы по разработке и отладке

Если вы не уверены, какие именно асинхронные методы доступны для вашей компоненты, воспользуйтесь отладчиком 1С. После инициализации объекта компоненты поставьте точку останова и раскройте дерево свойств объекта в табло. Вы увидите, что в списке методов объекта появились новые пункты с префиксами Начать..., которые платформа создала динамически на основе описания свойств в метаданных компоненты.

Также рекомендуется всегда проверять свойство ЗначениеСвойства на Неопределено в обработчике завершения получения. Это поможет избежать ошибок, если компонента не смогла отдать данные из-за внутреннего сбоя или отсутствия инициализации оборудования.

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

← На главную