Промисэз, промисэз. Асинхронность и многопоточность

08.11.22

Разработка - Универсальные функции

В 1С появились методы, позволяющие писать код без "ОписанийОповещений". Отличная новость!

"Promises, promises" группы Naked eyes

 

 

Я уверен, что именно эта песня играла, когда выбирался подход для реализации асинхронности в 1С.

Распространённое заблуждение - смешивание понятий асинхронных процедур и функций и многопоточности. Вот реализация асинхронных процедур:

&НаКлиенте 
Асинх Процедура КопируемыйФайлНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)

Диалог    = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Обещание  = Диалог.ВыбратьАсинх();

Попытка
	Результат  = Ждать Обещание;
	Если ТипЗнч(Результат) = Тип("Массив") И Результат.Количество() Тогда
		КопируемыйФайл = Результат[0];
	Иначе
		Возврат;
	КонецЕсли;
Исключение
	Сообщить(ИнформацияОбОшибке().Описание);	
КонецПопытки;

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

 

&НаКлиенте 
Асинх Процедура ЗапуститьКопированиеФайла(Команда)

ИмяКопируемогоФайла                = РазложитьПолноеИмяФайла(КопируемыйФайл).Имя; 
ОбещаниеСкопироватьФайл            = КопироватьФайлАсинх(КопируемыйФайл, Каталог + "\"+ ИмяКопируемогоФайла);
ОбещаниеПредупреждения             = ПредупреждениеАсинх("Файл копируется.", 1); 

Попытка
	Ждать ОбещаниеСкопироватьФайл;
Исключение                 
	Ждать ОбещаниеПредупреждения;  
	Сообщить(ОписаниеОшибки()); 
	Возврат;
КонецПопытки; 

Ждать ОбещаниеПредупреждения;  
ПредупреждениеАсинх("Файл скопирован."); 

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

Асинхронность проще воспринимать как нарезанный хлеб, который вы положили под матрас и ушли по своим делам, а когда захотели сухарей, то заглянули под него. С одним лишь отличием, что в этом матрасе есть вложенные матрасы :) Для многопоточной работы на клиенте мы можем использовать объект встроенного языка "Поток", доступный на клиенте:

&НаКлиенте 
Асинх Процедура ЗапуститьКопированиеФайла(Команда)
ИмяКопируемогоФайла                = РазложитьПолноеИмяФайла(КопируемыйФайл).Имя; 

ИсполняемыйКодПотокаКопирования        = "Ждать КопироватьФайлАсинх(КопируемыйФайл, Каталог + ""\""+ ИмяКопируемогоФайла)";
Идентификатор                          = Новый УникальныйИдентификатор();
ИдентификаторОбещанияПотокаКопирования = Новый Поток(ИсполняемыйКодПотокаКопирования,Идентификатор); 

//Какой-то код.

//А тут нам точно нужен результат.
Пока НЕ(ОбещаниеПотокаИсполнено(ИдентификаторОбещанияПотокаКопирования)) Цикл
КонецЦикла;

Результат = ОбещаниеПотока(ИдентификаторОбещанияПотокаКопирования);

Если НЕ(ТипЗнч(Результат) = Тип("Исключение")) Тогда
	ПолноеИмяСкопированногоФайла = Результат.ОбещаниеПотока;
Иначе         
	ВызватьИсключениеАсинх(Результат);
КонецЕсли;

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

На сервере для реализации многопоточности можно использовать связку из фоновых заданий и оповещений. Лучше использовать БСП. Для этого в форме напишем следующий код в форме:

&НаКлиенте
Процедура УвеличитьПоЧислуФоновыхЗаданий(Команда) 
	
	СброситьСчётчикНаСервере();
	ФоновоеЗадание = УвеличитьПоЧислуФоновыхЗаданийНаСервере(); 
	ОповещениеОПрогрессеВыполнения = Новый ОписаниеОповещения("ПрогрессВыполнения", ЭтотОбъект);
	НастройкиОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	НастройкиОжидания.ВыводитьОкноОжидания = Ложь;
	НастройкиОжидания.ОповещениеОПрогрессеВыполнения = ОповещениеОПрогрессеВыполнения;
	
	Обработчик = Новый ОписаниеОповещения("ПослеЗаписиЗагружаемыхДанныхОтчет", ЭтотОбъект);
	ДлительныеОперацииКлиент.ОжидатьЗавершение(ФоновоеЗадание, Обработчик, НастройкиОжидания);
	
КонецПроцедуры 

&НаСервере
Функция УвеличитьПоЧислуФоновыхЗаданийНаСервере()  
	
	ФЗ =	ВыполнитьПроцедуруМногопоточно();
	
	 Возврат ФЗ;  
	 
КонецФункции

&НаСервере
Функция ВыполнитьПроцедуруМногопоточно()
		
	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(ЭтаФорма.УникальныйИдентификатор);
	ПараметрыВыполнения.НаименованиеФоновогоЗадания = НСтр("ru = 'ТестированиеМногопоточности'");
	ПараметрыВыполнения.ЗапуститьВФоне = Истина;
	
	ПараметрыМетода = Новый Соответствие(); 
	
	Для Итератор = 1 По ЧислоФоновыхЗаданий Цикл
		МассивИтераторов = НОвый Массив();
		МассивИтераторов.Добавить(Итератор);  
		//ключ-не важен, параметры по порядку
		ПараметрыМетода.Вставить("ЗадержкаСекунд" + Итератор, МассивИтераторов);
	КонецЦикла;
	
	ФоновоеЗадание = ДлительныеОперации.ВыполнитьПроцедуруВНесколькоПотоков("ТестированиеСчетчика.ИнкрементироватьАсинх", 
		ПараметрыВыполнения, ПараметрыМетода);
		
	Возврат ФоновоеЗадание;
	
КонецФункции

&НаКлиенте
Процедура ПослеЗаписиЗагружаемыхДанныхОтчет(ФоновоеЗадание, ДополнительныеПараметры) Экспорт
	
	Если ФоновоеЗадание = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ФоновоеЗадание.Статус = "Выполнено" Тогда
		
	КонецЕсли;
	
	Если ФоновоеЗадание.Статус = "Ошибка" Тогда   
		
	КонецЕсли;
	
КонецПроцедуры

 &НаКлиенте
Процедура ПрогрессВыполнения(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат.Статус = "Выполняется" Тогда
		Прогресс = ПрочитатьПрогресс(Результат.ИдентификаторЗадания);
		Если Прогресс <> Неопределено Тогда  
			СчетчикВыполнения = СчетчикВыполнения + Число(Прогресс.Текст);

			Сообщить(СчетчикВыполнения);
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры 

&НаСервереБезКонтекста
Функция ПрочитатьПрогресс(ИдентификаторЗадания)
	Возврат ДлительныеОперации.ПрочитатьПрогресс(ИдентификаторЗадания);
КонецФункции

И в общем модуле:

Процедура ИнкрементироватьАсинх(ЗадержкаСекунд) Экспорт
	  
	  Если ЗадержкаСекунд  > 5  Тогда
		  ЗадержкаСекунд = 1;
	  КонецЕсли;
	  Генератор = НОвый ГенераторСлучайныхЧисел;
	  apПауза.ВыполнитьПаузу_ВСекундах(1,"Тестовая пауза"); 
	  ДлительныеОперации.СообщитьПрогресс(0,
	  1);
	  
КонецПроцедуры            
  

Осталось подождать, чтобы объект "Поток" перестал быть плодом воображения, Всем отличного дня!

Юмор асинхронность многопоточность

См. также

Планы обмена VS История данных

Перенос данных 1C Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    7170    dsdred    36    

114

1С-ная магия

Механизмы платформы 1С Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    19293    SeiOkami    46    

119

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    9603    YA_418728146    6    

143

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2300    28    progmaster    8    

3

Расширение глобального поиска 1С, или Глобальный поиск "на максималках"

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Мало кто знает, что поле "Глобального поиска" в 1С можно доработать. Добавить свои варианты поиска, кнопочки в результатах и даже целые пользовательские меню.

27.03.2023    7198    SeiOkami    10    

141

Версионирование объектов VS История данных

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Давайте разберемся в механизме «История данных» и поэкспериментируем для наглядности. Сравним «Версионирование объектов» и «Историю данных».

06.03.2023    20267    dsdred    56    

196

Практическая шпаргалка по новым возможностям языка запросов 1С

Механизмы платформы 1С Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

В предлагаемой статье решил привести примеры применения новых возможностей языка запросов 1С, начиная с версии платформы 8.3.20.

21.11.2022    24086    quazare    36    

123

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16445    144    sapervodichka    112    

130
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. gybson 08.11.22 15:54 Сейчас в теме
А откуда инфо, что ожидание не запускает отдельный поток, ведь текущий поток не прерывается.
2. пользователь 08.11.22 21:43
Сообщение было скрыто модератором.
...
3. FilatovRA 169 08.11.22 21:45 Сейчас в теме
(1) Если я правильно понял вопрос, то схема выглядит следующим образом(пишу на абстракциях): КопироватьФайлАсинх() → отправляет запрос на копирование в программу, которая занимается копированием, в ответ получает токен джоба. ЖДАТЬ - по токену бесконечно спрашивает программу копирования готов ли результат. Т.е. поток не создаётся, выделяется память для токена и всё.
4. gybson 09.11.22 09:05 Сейчас в теме
(3) Вызвать асинхронный метод платформы можно только внутри асинхронной процедуры, которая и будет фактически отдельным потоком.
5. FilatovRA 169 09.11.22 09:21 Сейчас в теме
(4) Вот статья на эту тему. Ключевое слово Асинх у процедуры как раз и создаёт её связь при интерпретации с механизмом "Ждать". Т.е. это указатель интерпретатору что в процедуре включена возможность хранения токена для "Ждать".
Оставьте свое сообщение