v8: Асинхронные вычисления без «заморозки» формы (на фоновых заданиях)В бытность свою студентом, курсе на 1, открыл для себя в Delphi замечательную возможность создания многопоточных приложений. По делу и без дела, делал многопоточными все свои поделки – было интересно, хоть тогда у меня еще не было многоядерных процессоров. Постепенно мозги привыкли к этому, и когда я занялся 1С 8, меня ожидало разочарование – запущенный из формы код замораживал не только саму форму, но и окно приложения заодно. Грустно. «Финты ушами» с использованием генератора «Внешних событий» по душе не пришлись. А до фоновых заданий в версии 1С 8.1 добрался только сейчас. | | Автор статьи: shachneff | Редакторы: oleg_km, dj_serega, Последняя редакция №2 от 08.08.08 | История URL: http://kb.mista.ru/article.php?id=696 | |
Ключевые слова: 1cv81, фоновое задание, асинхронно, многопоточность
Дано: 1С:Предприятие > 8.1.8, клиент-серверная архитектура, MS SQL.
Общий неглобальный серверный модуль. Обработка с одной формой, одной кнопкой и одним табличным полем.
Цель: Нажав кнопку на форме, запустить некий долгий алгоритм расчета так, чтобы при этом форма была доступна для нажатия других кнопок, менюшек, перемещения. По окончании расчета передать результат расчета в табличное поле и отобразить результат.
Методика: Как показала практика, из отработавшего фонового задания вернуть штатным путем каке-либо данные невозможно. Имеется 2 способа, позволяющих это делать:
1) фоновое задание пишет результат своей работы в БД, обработка отслеживает, что фоновое задание завершилось и считывает из БД результат. В качестве места хранения результата предлагается использовать регистр сведений, где измерение хранит UID экземпляра фонового задания, а ресурс имеет тип ХранилищеЗначений.
2) извращенный способ – передать значение через программную генерацию исключения (оператор «ВызватьИсключение»).
Решение:
Описывать способ с регистром сведений не буду, так как это достаточно просто реализовать, а минусом является необходимость добавления в конфигурацию регистра
сведений. Поэтому опишу вариант с «ВызватьИсключение»:
Процедура общего модуля:
Процедура ФоноваяПроцедура(Вход) Экспорт
ВремяСтарта = ТекущаяДата();
Длит = 15; //15 секунд
Пока (ТекущаяДата() - ВремяСтарта) < Длит Цикл
//холостой цикл-замедлитель
КонецЦикла;
//чтобы не передавать примитивные типы,
//создадим ТЗ из двух колонок, в одну из которых положим значение входного параметра,
// а во вторую - выходного
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Вход");
ТЗ.Колонки.Добавить("Выход");
НС = ТЗ.Добавить();
НС.Вход = Вход;
НС.Выход = ТекущаяДата() + 3600;
//упакуем объект ТаблицаЗначений и сериализуем его в строку. Для больших таблиц - хороший выигрыш в объеме.
Упаковано = ЗначениеВСтрокуВнутр(Новый ХранилищеЗначения(ТЗ, Новый СжатиеДанных(9)));
ВызватьИсключение Упаковано; //самое главное, обманем систему,сказав, что возникла ошибка и в качестве описания ошибки подсунем возвращаемое значение
КонецПроцедуры
|