В клиентской процедуре модуля формы есть переменная МояКомпонента. Необходимо дождаться, пока она инициализируется и только потом продолжить выполнение кода. При этом, чтобы это не было более 8 секунд. Как это лучше сделать? У меня такая мысль, но чувствую, что это не совсем рационально:
Если МояКомпонента = Неопределено Тогда
ВремяНачалаОжидания = ТекущаяУниверсальнаяДатаВМиллисекундах();
Пока МояКомпонента = Неопределено Цикл
Если ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачалаОжидания > 8 Тогда
Сообщить("Компонента не инициализирована, попробуйте позже");
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если МояКомпонента = Неопределено Тогда
Возврат;
КонецЕсли;
МояКомпонента.Метод4();
(1)
Если стоит винда то можешь использовать это - оно менее требовательно к ресурсам
Процедура Пауза(Интервал = 8) Экспорт
Компьютер=".";
Локатор=Новый COMОбъект("wbemscripting.swbemlocator");
Сервис=Локатор.ConnectServer(Компьютер,"root\cimv2","","","","",128);
Время = Сервис.ExecNotificationQuery("Sel ect * fr om __instancemodificationevent WITHIN 1 where TargetInstance isa 'Win32_LocalTime' and TargetInstance.Second="+Секунда(ТекущаяДата()+Интервал));
СледующееСобытие = Время.NextEvent();
КонецПроцедуры
Мои пять копеек. Не претендую сильно на оригинальность.
1. Создайте общую переменную Завершить, присвойте ей ложь.
2. Создайте процедуру ПрерватьИнициализацию в которой присваиваете Завершить = Истина;
3. Запустить ОбработчикОжидания процедуры ПрерватьИнициализацию на 8 сек. и однократным выполнением.
4. Запустить процедуру с кодом
Пока МояКомпонента = Неопределено или НЕ Завершить цикл
КонецЦикла;
В плане оптимизации и нагрузки такое себе, но в 1с с ожиданиями вообще мрак.
(10) Тут надо у ТС уточнять, чего он вообще хочет. На самом деле все варианты в общем-то такие себе, внятного способа решить это силами 1с нет и это очень плохо. Уже лет 15 только на моей памяти идут разговоры о нормальной паузе средствами языка, но воз и ныне там.
Все из предложенных решений создают нагрузку. Либо постоянно запускать обработчик ожидания, потом еще и отключать его, либо постоянно системное время получать и высчитывать. Я исходил из того, что как только компонента станет доступна мы сразу же идем дальше. Ну, а через 8 сек. это прерываем. И это не идеальное решение, но думаю не хуже остальных.
Кстати, еще вопрос о том как вообще идет инициализация компоненты, возможно не с той стороны копаем.
(11) В общем сделал так, оставляю тут, как заметку для себя. В веб клиенте пока работает всё как надо. Всем спасибо за идеи =)
&НаКлиенте
Процедура КомандаПечать(Команда)
// Тут начинается асинхронная инициализация компоненты
Если Не ОбщийМодульРаботаСОборудованием.ПроинициализироватьМоюКомпоненту() Тогда
Возврат;
КонецЕсли;
ВремяОжиданияСекунд = 8; // Это реквизит формы, тип Число
ПодключитьОбработчикОжидания("ПроверитьИнициализациюКомпоненты", 1, Ложь);
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьИнициализациюКомпоненты()
Если ВремяОжиданияСекунд < 1 Тогда
ОтключитьОбработчикОжидания("ПроверитьИнициализациюКомпоненты");
ТекстСообщения = НСтр("ru = 'Не удалось инициализировать компоненту оборудования.'");
ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстСообщения);
ИначеЕсли Не ГлобальныеКомпоненты.Свойство("МояКомпонента") Тогда // ГлобальныеКомпоненты - структура компонент (глобальная переменная в модуле приложения)
// Продолжаем ожидание
ВремяОжиданияСекунд = ВремяОжиданияСекунд - 1;
Иначе // Компонента МояКомпонента инициализирована
ОтключитьОбработчикОжидания("ПроверитьИнициализациюКомпоненты");
// Продолжаем работать с компонентой
ВыполнитьПечать();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Асинх Процедура ВыполнитьПечать()
МояКомпонента = ГлобальныеКомпоненты.МояКомпонента;
МояКомпонента.Метод4Async();
// ...
КонецПроцедуры