При переходе на современную модель разработки в среде 1С:Предприятие 8.3 программисты все чаще сталкиваются с необходимостью отказа от синхронных вызовов. Это связано с требованиями безопасности браузеров в веб-клиенте, особенностями работы мобильных платформ и общим стремлением к повышению отзывчивости интерфейса. Если с методами внешних компонент (ВК), работающих по технологии NativeAPI, все кажется интуитивно понятным (используется префикс НачатьВызов), то работа со свойствами часто вызывает вопросы. Разберем детально, как корректно организовать чтение и запись свойств компоненты в асинхронном коде.
В классическом (синхронном) режиме мы обращаемся к свойству внешней компоненты напрямую, как к реквизиту объекта. Проанализируем типичный пример:
// Синхронный подход
Включен = МояКомпонента.Активен; // Чтение свойства
МояКомпонента.Активен = Истина; // Установка свойства
Однако в режиме запрещенных синхронных вызовов (например, в веб-клиенте или при установленном свойстве конфигурации "Режим использования синхронных вызовов" в значение "Не использовать") такой код вызовет исключение. Платформа 1С требует, чтобы любое обращение, которое может привести к ожиданию ответа от внешней библиотеки, выполнялось асинхронно.
Выясним, какой механизм предоставляет платформа для чтения данных. Для каждого свойства, объявленного в компоненте, 1С автоматически генерирует метод с префиксом НачатьПолучение. Рассмотрим синтаксис этого вызова:
НачатьПолучение<ИмяСвойства>(<ОписаниеОповещения>)
Разберем по шагам процесс реализации на примере гипотетического свойства ВесОбъекта:
ОписаниеОповещения, указывающий на эту процедуру.Посмотрим на пример кода:
&НаКлиенте
Процедура УзнатьВес()
Оповещение = Новый ОписаниеОповещения("ПослеПолученияВеса", ЭтотОбъект, "ДополнительныйПараметрКонтекста");
МояКомпонента.НачатьПолучениеВесОбъекта(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПолученияВеса(ЗначениеСвойства, ДополнительныеПараметры) Экспорт
Если ЗначениеСвойства = Неопределено Тогда
Сообщить("Не удалось получить значение свойства");
Иначе
Сообщить("Текущий вес: " + ЗначениеСвойства);
Сообщить("Контекст: " + ДополнительныеПараметры);
КонецЕсли;
КонецПроцедуры
Важный нюанс: в процедуру-обработчик оповещения первым параметром всегда передается полученное значение свойства, а вторым — данные, которые вы передали при создании ОписаниеОповещения.
Аналогичным образом реализуется запись данных в компоненту. Платформа добавляет префикс НачатьУстановку к имени свойства. Рассмотрим структуру вызова:
НачатьУстановку<ИмяСвойства>(<ОписаниеОповещения>, <НовоеЗначение>)
Проанализируем пример установки свойства ЗаголовокОкна:
&НаКлиенте
Процедура УстановитьЗаголовок()
НовоеЗначение = "Рабочее место оператора";
Оповещение = Новый ОписаниеОповещения("ПослеУстановкиЗаголовка", ЭтотОбъект);
// Вызываем асинхронную установку
МояКомпонента.НачатьУстановкуЗаголовокОкна(Оповещение, НовоеЗначение);
КонецПроцедуры
&НаКлиенте
Процедура ПослеУстановкиЗаголовка(ДополнительныеПараметры) Экспорт
// Здесь нет параметра "Значение", так как мы его устанавливали
Сообщить("Свойство успешно обновлено в компоненте");
КонецПроцедуры
Обратите внимание, что в процедуре обратного вызова при установке свойства отсутствует параметр со значением — возвращаются только дополнительные параметры контекста. Если при установке в C++ коде компоненты возникнет ошибка (метод SetPropVal вернет false), платформа может инициировать исключение или передать информацию через другие механизмы оповещения в зависимости от реализации.
Многих разработчиков интересует вопрос: нужно ли в коде самой DLL на языке C++ описывать методы НачатьПолучение...? Нет, этого делать не нужно.
Платформа 1С:Предприятие реализует «обертку» (wrapper) над объектом внешней компоненты. Когда вы вызываете НачатьПолучение или НачатьУстановку, платформа перехватывает это обращение. Она самостоятельно создает поток ожидания или использует механизмы событийного цикла (в веб-клиенте), после чего вызывает стандартные методы интерфейса IComponentBase: GetPropVal для чтения и SetPropVal для записи.
Однако для корректной работы этого механизма необходимо соблюдение двух условий:
ComponentBase.h), поставляемых с SDK 1С.Рассмотрим, почему использование асинхронных методов для свойств критично в разных средах исполнения:
Начать... методов позволяет избежать блокировки интерфейса.Если вы не уверены, какие именно асинхронные методы доступны для вашей компоненты, воспользуйтесь отладчиком 1С. После инициализации объекта компоненты поставьте точку останова и раскройте дерево свойств объекта в табло. Вы увидите, что в списке методов объекта появились новые пункты с префиксами Начать..., которые платформа создала динамически на основе описания свойств в метаданных компоненты.
Также рекомендуется всегда проверять свойство ЗначениеСвойства на Неопределено в обработчике завершения получения. Это поможет избежать ошибок, если компонента не смогла отдать данные из-за внутреннего сбоя или отсутствия инициализации оборудования.
Подводя итог, можно сказать: свойства во внешних компонентах 1С продолжают существовать и активно использоваться, просто способ взаимодействия с ними в современном асинхронном мире стал чуть более многословным, но при этом гораздо более надежным.