Коллеги, подскажите, никак не разберусь с асинхронностью на клиенте, или может неправильно понимаю ее использование.
Описание ситуации:на клиенте(не на сервере) выполняется "тяжелая и долгая" процедура (длится около 2х минут, по факту - формирование объемного Word-файла). Всё это время 1С "висит". Хочется, чтобы пользователь мог продолжать работать с программой, пока процедура выполняется.
Если я правильно понимаю, нужно выделить процедуру в асинхронный процесс?
Пробовала через ОписаниеОповещения и ВыполнитьОбработкуОповещения, но 1С всё равно висит пока процедура не завершится.
Вот мой пример кода команды на форме:
&НаКлиенте
Процедура ЗапускАсинхроннойПроцедуры1(Команда)
Сообщить (ТекущаяДата());
ОченьДолгаяПроцедураНаКлиенте1(Новый ОписаниеОповещения("ЗавершениеДолгойПроцедуры", ЭтотОбъект));
КонецПроцедуры
&НаКлиенте
Процедура ОченьДолгаяПроцедураНаКлиенте1(Знач Оповещение) Экспорт
Счетчик = 1;
Для Сч = 1 По 5000000 Цикл
Для Сч = 1 По 5000000 Цикл
Для Сч = 1 По 5000000 Цикл
Счетчик = Счетчик + 1;
// что-то долго делаем
КонецЦикла;
КонецЦикла;
КонецЦикла;
ВыполнитьОбработкуОповещения(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ЗавершениеДолгойПроцедуры(Результат, ДополнительныеПараметры) Экспорт
Сообщить (ТекущаяДата());
КонецПроцедуры
Показать
В сети нашла примеры в основном асинхронных серверных вызовов (например, через фоновые процессы), но применить эти методику на клиентский вызов нельзя.
Может это делается вообще как-то проще без всякой асинхронности, но примеров найти не смогла.
Примеры, описанные в официальном мануале, не смогла применить на свой случай (там больше описано про диалоговые окна и вопросы).
На скрине 1 - нажата кнопка, и видно что 1С "висит".
На скрине 2 - вывод обоих сообщений только после завершения процедуры.
(1) исходя из самой постановки вопроса, это вообще невозможно в рамках одного клиентского сеанса.
Сам клиентский сеанс всегда выполняется в один поток. Вся клиентская асинхронность исходит из того, что поток не забит. Просто не ожидается последовательное выполнение конкретной задачи. То же самое, что ОбработкаОжидания. Ключевое слово "Ожидания", т.е. когда клиентский поток находится в режиме ожидания.
Переделывайте алгоритм на вынос части задач на сервер.
Тут нет async await :)
Во первых , зачем вы делаете трудоемкие процессы на клиенте?
Для того и сделали Тонкий клиент, чтобы использовать всю мощь сервера, при этом выполняя асинхронные процессы там вы не тормозите клиента.
В вашем варианте - это похоже на странный мазохизм загрузить клиента по некуда больше , и жаловаться - "тормозит."..
Вы не с обычных форм переучиваетесь?
Нет, на обычных формах не работала, с C# работала ;)
Я полностью понимаю Ваш ответ, но тут исключение: процедура формирует Word-документ. На сервере компоненты офиса не установлены. К тому же поставлена задача - не нагружать этим сервер, и пусть это делает тот клиент, которому понадобилось сформировать этот "большой" документ (почти под 200 страниц).
(3) Ясно, ну тогда смиритесь с зависанием этого экземляра клиента....
И просто запускайте еще один экземпляр базы и работайте там пока не отвиснет первый . Не надо никаких асинхронностей вообще.
Простота - сестра гениальности
(5) жалко, а то была идея - дать задание на формирование 10-15 Word-файлов, а пользователь пока работал бы с программой, а потом она бы ему отчиталась от завершении. Предложение с запуском второго экземпляра в принципе тоже вариант )
(3) как вариант запускать отдельный клиентский сеанс (можно прямо из конкретного сеанса) под это дело и уже полученный документ открывать в нужном сеансе.
ФоновыеЗадания "живут" в контексте сервера и толстого клиента.
Т.е. чисто теоретически мы можем запустить выполнение в фоне на клиенте при условии, что последний толстый.
Однако, типовые механизмы заточены на вызов фона посредством сервера.
Предлагаю рассмотреть общий модуль
СтандартныеПодсистемыСервер и методы в нем
- ЗапуститьФоновоеЗаданиеСКонтекстомКлиента
- ПередЗапускомФоновогоЗаданияСКонтекстомКлиента
после осмысления кода, думаю, в толстом клиенте можно слепить костыль.
(7) спасибо за предложение, посмотрю, что можно там найти. У нас все клиенты автоматом "тонкие", но конкретно под эту задачу можно просить клиента запускаться "толстым", чтобы не мучался ожиданием, т.к. таких тяжелых документов надо ему будет делать штук по 100 (но, хорошо, что редко).
ФоновыеЗадания "живут" в контексте сервера и толстого клиента.
Т.е. чисто теоретически мы можем запустить выполнение в фоне на клиенте при условии, что последний толстый.
Толстый клиент упоминается только в рамках файловой базы. Что в данном случае не подходит.
В клиент-серверном - только на сервере. Причем фоновыми заданиями управляет планировщик заданий, который физически находится в менеджере кластера и конкретное фоновое задание может выполняться в любом наименее нагруженном рабочем процессе.
(10) В какой момент? Вызов для отработки длительной процедуры? Или длительную оставить в основной, а клиента перенаправить в новый экземпляр? А не зависнут ли они тогда оба?
В общем, если покопаться, то можно попытаться сделать запуск процесса на стороне толстого клиента, но это требует дополнительного анализа и изучения данного вопроса. Может быть, если задача будет стоять более остро, доделаю ее как-нибудь. Сейчас просто показываю на клиенте ход процесса при помощи функции Состояние().
Если я правильно понял код и задачу - у вас желаемого результата из этого кода не получится.
КонецЦикла;
ВыполнитьОбработкуОповещения(Оповещение);
// асинхронность была бы здесь, но не будет
КонецПроцедуры
&НаКлиенте
Процедура ЗавершениеДолгойПроцедуры(Результат, ДополнительныеПараметры) Экспорт
Показать
Даже, если бы тут вообще где-то была асинхронность, она была бы там, где я отметил комментарием. Но здесь вообще нет никакой асинхронности, весь код будет выполняться синхронно. Вначале долго будет висеть счётчик (синхронный), а потом выполнится обработка оповещения (синхронная). На данный момент, кроме фоновых заданий и встроенных асинхронных функций, 1С НЕ предоставляет средств работы с асинхронностью.
Могу посоветовать только такой вариант - пишите форму-пустышку, пишите такой код:
А уже все тяжёлые процедуры вызываете в форме-пустышке в ПриОткрытии, не забывая в конце тяжёлых процедур вызвать Закрыть().
Т.е. хитрим и используем встроенный асинхронный метод. Сам я такой фокус не пробовал, поэтому гарантировать результат не могу, но ничего другого придумать не смог.