Наверное, вы согласитесь, что длительные операции, которые запускаются интерактивно и блокируют интерфейс пользователя, это крайне неудобно. Особенно в Web-клиенте, где это может вызвать тайм-аут и появление непонятных окон у пользователя.
Для решения вопроса выполнения длительных операций используются фоновые задания и обработчики ожидания на клиенте, которые раз в определенный интервал времени проверяют, выполнено ли фоновое задание.
В Интернете есть множество примеров, как это сделать неудобно. Благодаря БСП 2.3 мы можем запустить выполнение длительной операции с выводом формы длительной операции («крутящееся колёсико») и сообщение прогресса выполнения буквально в несколько строк кода.
Рассмотрим тестовую задачу.
Имеется обработка, с формы которой по нажатию кнопки требуется запускать длительные вычисления, результат которых выводится в ту же форму обработки. Во время выполнения фонового задания нужно выводить неблокирующую форму длительной операции.
Для решения задачи:
- Создадим серверный общий модуль, который будет содержать процедуру фонового задания:
В коде общего модуля разместим процедуру фонового задания и процедуру, выполняющую длительную операцию — паузу:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
Процедура ПроизвестиДлительноеВычисление(СтруктураПараметров, АдресХранилища) Экспорт Пауза(7000); ПоместитьВоВременноеХранилище("Михаил Щербаков", АдресХранилища); КонецПроцедуры // Делает паузу на указанное количество миллисекунд // // Параметры: // ПаузаВМс - Число - длительность паузы в миллисекундах // Процедура Пауза(ПаузаВМс) Экспорт Скрипт=Новый ТекстовыйДокумент(); Скрипт.УстановитьТекст ("if (WScript.Arguments.Count()==0) | WScript.Quit(); |else | if (isNaN(parseInt(WScript.Arguments(0)))) | WScript.Quit(); |WScript.Sleep(WScript.Arguments(0));"); GUID = Новый УникальныйИдентификатор; ИмяФайлаСкрипта = КаталогВременныхФайлов() + GUID + "_sleep.js"; Скрипт.Записать(ИмяФайлаСкрипта, КодировкаТекста.ANSI); WshShell = Новый COMОбъект("wscript.shell"); WshShell.Run("wscript.exe """ + ИмяФайлаСкрипта + """ " + Формат(ПаузаВМс, "ЧГ=0"), 0, -1); УдалитьФайлы(ИмяФайлаСкрипта); КонецПроцедуры |
2. Создадим обработку «ТестоваяОбработка» с формой обработки.
3. На форме обработки создадим реквизит формы «ДлительнаяОперация» с типом «Произвольный».
В этом пункте заключается одно из основных отличий от других примеров обработки длительных операций. Нужно создать всего навсего один реквизит, а не несколько (в других примерах упоминаются реквизиты «АдресХранилища» и «ИдентификаторЗадания»).
В БСП 2.3 нужен всего один реквизит формы, который будет хранить структуру со всеми свойствами запущенного задания.
4. Также создаём реквизит формы «РезультатВычислений», в который фоновое задание вернёт результат.
5. В обработчике нажатия кнопки размещаем следующий код:
1 2 3 4 5 6 7 8 9 10 11 |
&НаКлиенте Процедура ЗапуститьДлительныеВычисления(Команда) // вызываем серверную процедуру формы для запуска длительной операции ЗапуститьДлительныеВычисленияНаСервере(); // инициализируем параметры ожидания (посмотрите документацию, там можно включить режим вывода прогресса выполнения и методами СообщитьПрогресс/ПрочитатьПрогресс указывать прогресс выполнения операции ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтаФорма); // подключаем обработчик ожидания и указываем описание оповещения о завершении задания ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, Новый ОписаниеОповещения("ПриЗавершенииДлительнойОперации", ЭтаФорма), ПараметрыОжидания); |
Также в модуле формы требуется еще два метода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
&НаКлиенте Процедура ПриЗавершенииДлительнойОперации(Результат, ДополнительныеПараметры) Экспорт // данный код сработает после завершения работы задания автоматически РезультатВычислений = ПолучитьИзВременногоХранилища(ДлительнаяОперация.АдресРезультата); КонецПроцедуры &НаСервере Процедура ЗапуститьДлительныеВычисленияНаСервере() // код запуска длительной операции посредством БСП ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор); ПараметрыВыполнения.НаименованиеФоновогоЗадания = НСтр("ru = 'Длительное вычисление'"); // далее в "Новый Структура" можно поместить нужные фоновому заданию параметры ДлительнаяОперация = ДлительныеОперации.ВыполнитьВФоне("test_Вычисления.ПроизвестиДлительноеВычисление", Новый Структура, ПараметрыВыполнения); КонецПроцедуры |
Вот и всё. Не нужно самим создавать никаких обработчиков ожидания и избыточных методов/реквизитов. Всё уже сделано за нас разработчиками БСП 2.3.
Форма длительной операции:
Результат работы длительной операции — в поле ввода появился текст:
Данный код можно легко модифицировать под свои нужды. Удачи!