Асинхронный вызов клиентской процедуры

1. ellavs 1027 19.03.19 11:27 Сейчас в теме
1С:Предприятие 8.3 (8.3.12.1567)

Коллеги, подскажите, никак не разберусь с асинхронностью на клиенте, или может неправильно понимаю ее использование.

Описание ситуации: на клиенте (не на сервере) выполняется "тяжелая и долгая" процедура (длится около 2х минут, по факту - формирование объемного Word-файла). Всё это время 1С "висит".
Хочется, чтобы пользователь мог продолжать работать с программой, пока процедура выполняется.
Если я правильно понимаю, нужно выделить процедуру в асинхронный процесс?

Пробовала через ОписаниеОповещения и ВыполнитьОбработкуОповещения, но 1С всё равно висит пока процедура не завершится.

Вот мой пример кода команды на форме:

&НаКлиенте
Процедура ЗапускАсинхроннойПроцедуры1(Команда)
	Сообщить (ТекущаяДата());
	ОченьДолгаяПроцедураНаКлиенте1(Новый ОписаниеОповещения("ЗавершениеДолгойПроцедуры", ЭтотОбъект));
КонецПроцедуры

&НаКлиенте
Процедура ОченьДолгаяПроцедураНаКлиенте1(Знач Оповещение) Экспорт
	Счетчик = 1;
	Для Сч = 1 По 5000000 Цикл 
		Для Сч = 1 По 5000000 Цикл 
			Для Сч = 1 По 5000000 Цикл 
				Счетчик = Счетчик + 1;
				// что-то долго делаем
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;                 
	ВыполнитьОбработкуОповещения(Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ЗавершениеДолгойПроцедуры(Результат, ДополнительныеПараметры) Экспорт
	Сообщить (ТекущаяДата());
КонецПроцедуры
Показать


В сети нашла примеры в основном асинхронных серверных вызовов (например, через фоновые процессы), но применить эти методику на клиентский вызов нельзя.
Может это делается вообще как-то проще без всякой асинхронности, но примеров найти не смогла.
Примеры, описанные в официальном мануале, не смогла применить на свой случай (там больше описано про диалоговые окна и вопросы).

На скрине 1 - нажата кнопка, и видно что 1С "висит".
На скрине 2 - вывод обоих сообщений только после завершения процедуры.
Прикрепленные файлы:
Dementor; G_101343795907160391674; +2 Ответить
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
15. spacecraft 08.04.19 19:55 Сейчас в теме
(1) исходя из самой постановки вопроса, это вообще невозможно в рамках одного клиентского сеанса.
Сам клиентский сеанс всегда выполняется в один поток. Вся клиентская асинхронность исходит из того, что поток не забит. Просто не ожидается последовательное выполнение конкретной задачи. То же самое, что ОбработкаОжидания. Ключевое слово "Ожидания", т.е. когда клиентский поток находится в режиме ожидания.

Переделывайте алгоритм на вынос части задач на сервер.
Тут нет async await :)
18. spacecraft 08.04.19 20:26 Сейчас в теме
(1) а можно совсем просто поступить. Пусть долго выполняется. Показать, что можно еще раз открыть 1С и продолжить работать в новом сеансе.
2. YannikAlx 43 19.03.19 11:57 Сейчас в теме
Во первых , зачем вы делаете трудоемкие процессы на клиенте?
Для того и сделали Тонкий клиент, чтобы использовать всю мощь сервера, при этом выполняя асинхронные процессы там вы не тормозите клиента.

В вашем варианте - это похоже на странный мазохизм загрузить клиента по некуда больше , и жаловаться - "тормозит."..
Вы не с обычных форм переучиваетесь?
3. ellavs 1027 19.03.19 12:02 Сейчас в теме
Нет, на обычных формах не работала, с C# работала ;)
Я полностью понимаю Ваш ответ, но тут исключение: процедура формирует Word-документ. На сервере компоненты офиса не установлены. К тому же поставлена задача - не нагружать этим сервер, и пусть это делает тот клиент, которому понадобилось сформировать этот "большой" документ (почти под 200 страниц).
5. YannikAlx 43 19.03.19 12:10 Сейчас в теме
(3) Ясно, ну тогда смиритесь с зависанием этого экземляра клиента....
И просто запускайте еще один экземпляр базы и работайте там пока не отвиснет первый . Не надо никаких асинхронностей вообще.
Простота - сестра гениальности
9. ellavs 1027 19.03.19 13:45 Сейчас в теме
(5) жалко, а то была идея - дать задание на формирование 10-15 Word-файлов, а пользователь пока работал бы с программой, а потом она бы ему отчиталась от завершении. Предложение с запуском второго экземпляра в принципе тоже вариант )
16. spacecraft 08.04.19 19:58 Сейчас в теме
(3) как вариант запускать отдельный клиентский сеанс (можно прямо из конкретного сеанса) под это дело и уже полученный документ открывать в нужном сеансе.
4. arsen_botashev 19.03.19 12:05 Сейчас в теме
6. YannikAlx 43 19.03.19 12:18 Сейчас в теме
А вообще механизм асинхронностьи зарыт вот здесь....

ЗаданиеРезультат = ДлительныеОперации.ЗапуститьВыполнениеВФоне(

И оно ясно только на сервере...
7. VmvLer 19.03.19 13:22 Сейчас в теме
ФоновыеЗадания "живут" в контексте сервера и толстого клиента.

Т.е. чисто теоретически мы можем запустить выполнение в фоне на клиенте при условии, что последний толстый.

Однако, типовые механизмы заточены на вызов фона посредством сервера.

Предлагаю рассмотреть общий модуль
СтандартныеПодсистемыСервер и методы в нем
- ЗапуститьФоновоеЗаданиеСКонтекстомКлиента
- ПередЗапускомФоновогоЗаданияСКонтекстомКлиента

после осмысления кода, думаю, в толстом клиенте можно слепить костыль.
8. ellavs 1027 19.03.19 13:42 Сейчас в теме
(7) спасибо за предложение, посмотрю, что можно там найти. У нас все клиенты автоматом "тонкие", но конкретно под эту задачу можно просить клиента запускаться "толстым", чтобы не мучался ожиданием, т.к. таких тяжелых документов надо ему будет делать штук по 100 (но, хорошо, что редко).
17. spacecraft 08.04.19 20:12 Сейчас в теме
(7)
ФоновыеЗадания "живут" в контексте сервера и толстого клиента.

Т.е. чисто теоретически мы можем запустить выполнение в фоне на клиенте при условии, что последний толстый.

Толстый клиент упоминается только в рамках файловой базы. Что в данном случае не подходит.
В клиент-серверном - только на сервере. Причем фоновыми заданиями управляет планировщик заданий, который физически находится в менеджере кластера и конкретное фоновое задание может выполняться в любом наименее нагруженном рабочем процессе.
10. SlavaKron 19.03.19 14:46 Сейчас в теме
А что если запустить новый экземпляр клиента через КомОбъект?
11. ellavs 1027 19.03.19 17:10 Сейчас в теме
(10) В какой момент? Вызов для отработки длительной процедуры? Или длительную оставить в основной, а клиента перенаправить в новый экземпляр? А не зависнут ли они тогда оба?
12. SlavaKron 19.03.19 17:15 Сейчас в теме
(11) Не обращайте внимания. Действительно, зависнут оба.
13. ellavs 1027 28.03.19 12:22 Сейчас в теме
В общем, если покопаться, то можно попытаться сделать запуск процесса на стороне толстого клиента, но это требует дополнительного анализа и изучения данного вопроса. Может быть, если задача будет стоять более остро, доделаю ее как-нибудь. Сейчас просто показываю на клиенте ход процесса при помощи функции Состояние().
14. for_sale 971 08.04.19 18:59 Сейчас в теме
Если я правильно понял код и задачу - у вас желаемого результата из этого кода не получится.

КонецЦикла;                 
    ВыполнитьОбработкуОповещения(Оповещение);

// асинхронность была бы здесь, но не будет

КонецПроцедуры

&НаКлиенте
Процедура ЗавершениеДолгойПроцедуры(Результат, ДополнительныеПараметры) Экспорт
Показать


Даже, если бы тут вообще где-то была асинхронность, она была бы там, где я отметил комментарием. Но здесь вообще нет никакой асинхронности, весь код будет выполняться синхронно. Вначале долго будет висеть счётчик (синхронный), а потом выполнится обработка оповещения (синхронная). На данный момент, кроме фоновых заданий и встроенных асинхронных функций, 1С НЕ предоставляет средств работы с асинхронностью.

Могу посоветовать только такой вариант - пишите форму-пустышку, пишите такой код:

&НаКлиенте
Процедура ЗапускАсинхроннойПроцедуры1(Команда)
    Сообщить (ТекущаяДата());
    ОткрытьФорму("ФормаПустышка", Новый ОписаниеОповещения("ЗавершениеДолгойПроцедуры", ЭтотОбъект));
КонецПроцедуры

&НаКлиенте
Процедура ЗавершениеДолгойПроцедуры(Результат, ДополнительныеПараметры) Экспорт
    Сообщить (ТекущаяДата());
    ПоказатьОповещениеПользователя("Я закончилось!!!");
КонецПроцедуры
Показать


А уже все тяжёлые процедуры вызываете в форме-пустышке в ПриОткрытии, не забывая в конце тяжёлых процедур вызвать Закрыть().

Т.е. хитрим и используем встроенный асинхронный метод. Сам я такой фокус не пробовал, поэтому гарантировать результат не могу, но ничего другого придумать не смог.
19. ellavs 1027 08.04.19 22:12 Сейчас в теме
(14) интересное решение, можно попробовать. Спасибо.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот