Многопоточный режим выполнения процедуры с помощью методов БСП - примеры разработки

01.04.22

Разработка - БСП (Библиотека стандартных подсистем)

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

 

Введение

Всем доброго времени суток! В этой статье я решил привести небольшой программный эксперимент - позапускать собственную процедуру общего модуля конфигурации в многопоточном режиме, используя относительно новые методы библиотеки стандартных подсистем - набора модулей ДлительныеОперации. Разработку примеров я буду вести на типовой конфигурации БСП - версии 3.1.6.137 на Платформе 1с 8.3.20.1674. Однако, я пока не берусь утверждать, что данный подход можно использовать в любой современной конфигурации, в основе которой лежит БСП - поскольку этот функционал относительно новый. Но, со временем, его можно будет применить.

Статью разобью стандартной на две части - в первой части я опишу процедуру, которая должна будет запускаться многопоточно, во второй части - опишу практическое использование запуска в несколько потоков  -  ВыполнитьПроцедуруВНесколькоПотоков.

Переходим к первой части статьи.

 

Напишем процедуру, которая будет использоваться в многопоточном запуске

В собственном общем модуле конфигурации (я работаю на типовой БСП 3.1.6.13), создаем искусственную процедуру, которую будем использовать в многопоточном запуске. Выглядит она пусть так:

 
 ОбщийМодуль1.ПроцедураМногопоток
&НаСервере
Процедура ПроцедураМногопоток(Поток, Параметры) Экспорт
  
	КоличествоСозданныхОбъектов = 0;
	
	Если Параметры.ТипОбработки = "Вариант 1" Тогда // Создадим 500 документов поступления  (можно и загрузить)
		
		Для Счетчик = 1 по 500 Цикл
			
			НовДок = Документы._ДемоПоступлениеТоваров.СоздатьДокумент();
			НовДок.Дата = ТекущаяДата();
			НовДок.Организация = Параметры.Организация;
			НовДок.Валюта = Справочники.Валюты.НайтиПоКоду("643"); 
			НовДок.Комментарий = Параметры.КомментарийДокумента;
			
			Попытка      
				НовДок.Записать(РежимЗаписиДокумента.Запись);
			Исключение
				
			КонецПопытки;	
			
			КоличествоСозданныхОбъектов = КоличествоСозданныхОбъектов + 1; 
			
		КонецЦикла;
		
	ИначеЕсли Параметры.ТипОбработки = "Вариант 2" Тогда	// Создадим 1000 записей справочника "Номенклатура"

		Для Счетчик = 1 по 1000 Цикл
			
			НовСпр = Справочники._ДемоНоменклатура.СоздатьЭлемент();
			НовСпр.Наименование = "Новая номенклатура_"+Строка(Счетчик);
			НовСпр.НаименованиеДляПечати = "Новая номенклатура_"+Строка(Параметры.ОписаниеСправочника);
			НовСпр.Записать();
			
		КонецЦикла;
		
		КоличествоСозданныхОбъектов = КоличествоСозданныхОбъектов + 1;
		
	КонецЕсли;
	
КонецПроцедуры

 

 

При первом типе обработке - "Вариант 1", процедура - будет создать 500 документов. При втором типе - "Вариант 2" - запустим цикл по созданию 1000 элементов справочника "Номенклатура".

Теперь, перейдем к коду обработки, использующим ДлительныеОперации, запускающим ж

 

Описание функционала запуска с помощью функции "ВыполнитьПроцедуруВНесколькоПотоков"

 

Для начала нарисуем вот такую форму:

Рис.1 Форма тестирования многопотоковой функции в БСП

 

Напишем процедуру клиентского запуска. Выглядит она вот так:

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

	Обработчик = Новый ОписаниеОповещения("ОбработатьДанные", ЭтотОбъект);
	ДлительныеОперацииКлиент.ОжидатьЗавершение(Задание, Обработчик, НастройкиОжидания);
	
	
КонецПроцедуры

 

 

Далее, опишем функцию СоздадимПотокиНаСервере(УИД)

 
 Создадим потоки на сервере

 

&НаСервере
Функция СоздадимПотокиНаСервере(УникальныйИдентификатор)

	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
	ПараметрыВыполнения.НаименованиеФоновогоЗадания = НСтр("ru = 'Выполнение многопоточной функции'");
	ПараметрыВыполнения.ЗапуститьВФоне = Истина;
	
	ПараметрыМетода = Новый Соответствие();

	// ===== первый поток выполнения =====
	
	КодПотока = "Поток 1";
	ПараметрыПотока 						= ПараметрыМногопоточнойФункции();
	ПараметрыПотока.ТипОбработки 			= "Вариант 1";
	ПараметрыПотока.ОписаниеСправочника 	= Объект.ОписаниеСправочника; 
	ПараметрыПотока.КомментарийДокумента 	= Объект.КомментарийДокумента;
	ПараметрыПотока.Организация           	= Объект.Организация;	
	
	ПараметрыВызоваСервера = Новый Массив;
	ПараметрыВызоваСервера.Добавить(КодПотока); 		 // КодПотока
	ПараметрыВызоваСервера.Добавить(ПараметрыПотока);    // Параметры функции в потоке
	
	ПараметрыМетода.Вставить(КодПотока,ПараметрыВызоваСервера); 
	
	// ===== второй поток выполнения =====
	
	КодПотока = "Поток 2";
	ПараметрыПотока 						= ПараметрыМногопоточнойФункции();
	ПараметрыПотока.ТипОбработки 			= "Вариант 2";
	ПараметрыПотока.ОписаниеСправочника 	= Объект.ОписаниеСправочника; 
	ПараметрыПотока.КомментарийДокумента 	= Объект.КомментарийДокумента;
	ПараметрыПотока.Организация           	= Объект.Организация;	
	
	ПараметрыВызоваСервера = Новый Массив;
	ПараметрыВызоваСервера.Добавить(КодПотока); 		 // КодПотока
	ПараметрыВызоваСервера.Добавить(ПараметрыПотока);    // Параметры функции в потоке
	
	ПараметрыМетода.Вставить(КодПотока,ПараметрыВызоваСервера); 	
	
	// =================================== 
	
	ИмяФункцииИлиПроцедуры = "ОбщийМодуль1.ПроцедураМногопоток";
	
	ФоновоеЗадание = ДлительныеОперации.ВыполнитьПроцедуруВНесколькоПотоков(ИмяФункцииИлиПроцедуры, ПараметрыВыполнения, ПараметрыМетода);
		
   	Если ФоновоеЗадание.Статус = "Ошибка" Тогда
		Сообщить(СокрЛП(ФоновоеЗадание.Статус));
	КонецЕсли;

	
	Возврат ФоновоеЗадание;	
	
КонецФункции

&НаСервере
Функция ПараметрыМногопоточнойФункции()
	
	Результат = Новый Структура();
	Результат.Вставить("ТипОбработки", 0);
	Результат.Вставить("ОписаниеСправочника", "");
	Результат.Вставить("КомментарийДокумента", "");
	Результат.Вставить("Организация", Справочники._ДемоОрганизации.ПустаяСсылка());
	Результат.Вставить("ЗагружатьПорциями", Истина);
	Возврат Результат;
	
КонецФункции

 

Здесь, я обозначаю условные параметры для двух потоков "Поток 1" и "Поток 2". Далее, использую Функцию "ВыполнитьПроцедуруВНесколькоПотоков" с этими параметрами.

 

Далее, опишем функции "ПрогрессВыполнения" и "ОбработатьДанные" (это будут чисто-условные "полупустые" функции)

 
 ПрогрессВыполнения и ОбработатьДанные

 

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

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

&НаКлиенте
Процедура ОбработатьДанные(Задание, ДополнительныеПараметры) Экспорт

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

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

 

Весь код модуля формы обработки вот такой (можно скопипастить):

 
 Весь код модуля формы обработки

 


&НаСервере
Функция ПараметрыМногопоточнойФункции()
	
	Результат = Новый Структура();
	Результат.Вставить("ТипОбработки", 0);
	Результат.Вставить("ОписаниеСправочника", "");
	Результат.Вставить("КомментарийДокумента", "");
	Результат.Вставить("Организация", Справочники._ДемоОрганизации.ПустаяСсылка());
	Результат.Вставить("ЗагружатьПорциями", Истина);
	Возврат Результат;
	
КонецФункции	

&НаКлиенте
Процедура ЗапуститьМногопоток(Команда)
	
	ОповещениеОПрогрессеВыполнения = Новый ОписаниеОповещения("ПрогрессВыполнения", ЭтотОбъект);
	
	
	Задание = СоздадимПотокиНаСервере(УникальныйИдентификатор);
	
	//ИдентификаторЗадания = ПолучитьИЗВременногоХранилища(Задание.АдресРезультата).Получить("Поток 1").ИдентификаторЗадания;//Задание.ИдентификаторЗадания;
	
	ИдентификаторЗадания = Задание.ИдентификаторЗадания;
	//Сообщить(ИдентификаторЗадания);
	
	НастройкиОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	НастройкиОжидания.ВыводитьОкноОжидания = Ложь;
	НастройкиОжидания.ОповещениеОПрогрессеВыполнения = ОповещениеОПрогрессеВыполнения;
	НастройкиОжидания.ВыводитьПрогрессВыполнения = Истина;
	

	Обработчик = Новый ОписаниеОповещения("ОбработатьДанные", ЭтотОбъект);
	ДлительныеОперацииКлиент.ОжидатьЗавершение(Задание, Обработчик, НастройкиОжидания);
	
	
КонецПроцедуры

&НаСервере
Функция СоздадимПотокиНаСервере(УникальныйИдентификатор)

	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
	ПараметрыВыполнения.НаименованиеФоновогоЗадания = НСтр("ru = 'Выполнение многопоточной функции'");
	ПараметрыВыполнения.ЗапуститьВФоне = Истина;
	
	ПараметрыМетода = Новый Соответствие();

	// ===== первый поток выполнения =====
	
	КодПотока = "Поток 1";
	ПараметрыПотока 						= ПараметрыМногопоточнойФункции();
	ПараметрыПотока.ТипОбработки 			= "Вариант 1";
	ПараметрыПотока.ОписаниеСправочника 	= Объект.ОписаниеСправочника; 
	ПараметрыПотока.КомментарийДокумента 	= Объект.КомментарийДокумента;
	ПараметрыПотока.Организация           	= Объект.Организация;	
	
	ПараметрыВызоваСервера = Новый Массив;
	ПараметрыВызоваСервера.Добавить(КодПотока); 		 // КодПотока
	ПараметрыВызоваСервера.Добавить(ПараметрыПотока);    // Параметры функции в потоке
	
	ПараметрыМетода.Вставить(КодПотока,ПараметрыВызоваСервера); 
	
	// ===== второй поток выполнения =====
	
	КодПотока = "Поток 2";
	ПараметрыПотока 						= ПараметрыМногопоточнойФункции();
	ПараметрыПотока.ТипОбработки 			= "Вариант 2";
	ПараметрыПотока.ОписаниеСправочника 	= Объект.ОписаниеСправочника; 
	ПараметрыПотока.КомментарийДокумента 	= Объект.КомментарийДокумента;
	ПараметрыПотока.Организация           	= Объект.Организация;	
	
	ПараметрыВызоваСервера = Новый Массив;
	ПараметрыВызоваСервера.Добавить(КодПотока); 		 // КодПотока
	ПараметрыВызоваСервера.Добавить(ПараметрыПотока);    // Параметры функции в потоке
	
	ПараметрыМетода.Вставить(КодПотока,ПараметрыВызоваСервера); 	
	
	// =================================== 
	
	ИмяФункцииИлиПроцедуры = "ОбщийМодуль1.ПроцедураМногопоток";
	
	ФоновоеЗадание = ДлительныеОперации.ВыполнитьПроцедуруВНесколькоПотоков(ИмяФункцииИлиПроцедуры, ПараметрыВыполнения, ПараметрыМетода);
		
   	Если ФоновоеЗадание.Статус = "Ошибка" Тогда
		Сообщить(СокрЛП(ФоновоеЗадание.Статус));
	КонецЕсли;

	
	Возврат ФоновоеЗадание;	
	
КонецФункции	

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

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

&НаКлиенте
Процедура ОбработатьДанные(Задание, ДополнительныеПараметры) Экспорт

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


 

 

На видео исполнение процедуры выглядит вот так (не смог разместить здесь гиф-ку - поэтому ссылка на облако):

Открыть видео по ссылке

 

Заключение и выводы

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

 

 

 

Предыдущие материалы по выполнению функций и процедур в асинхронном режиме

Ранее, на портале я приводил небольшие примеры по использованию функций и процедур в асинхронных режимах в рамках библиотеки стандартных подсистем:

Гарантированно рабочий пример использования длительных операций на БСП с отображением прогресса. [Часть 1]

Запуск почти любых процедур и функции конфигураций в асинхронном режиме - БСП - Длительные операции [Часть 2]

БСП - рабочие примеры асинхронного запуска функций и процедур

Далее - другие материалы по разным возможностям библиотеки стандартных подсистем.

 

Мои материалы по возможностям Библиотеки стандартных подсистем (БСП)

Спасибо всем, кто прочитал до данного момента.

Также прошу ознакомиться с другими моими статьями по интересному функционалу типовых конфигураций в рамках библиотеки стандартных подсистем и по разделам. Я накопил достаточный объем знаний по данной библиотеки, вот наиболее интересные статьи по ней:

 

Возможности администрирования баз и кластера с помощью библиотеки стандартных подсистем:

Профили управления доступом к объектам в любой конфигурации на БСП

Журнал регистрации - основные методы работы через БСП

Базовые приемы работы с кластером 1С при помощи БСП

 

Работа со штрихкодами и печатными макетами с помощью библиотеки стандартных подсистем:

Генерация штрихкодов с помощью БСП для программистов

Полезные встроенные функции для работы с печатными формами и не только на УТ 11.4 и БП 3.0 (сравнение)

Печать макета MS Word в любом документе с помощью БСП

Префиксация объектов - полезный типовой функционал БСП

Работаем с контактной информацией в конфигурациях на БСП

 

Разные прикладные разработки:

Генератор маршрута по "документам отгрузки" в Google.Maps

Честный знак - запрос содержания упаковки по ее коду [табачная продукция]

Универсальный журнал документов для типовых конфигураций

См. также

Шаблон многопоточного выполнения фонового задания

Инструментарий разработчика БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Пример шаблона для многопоточного выполнения фонового задания на основе БСП. Шаблоны сделаны для процедуры и функции.

2 стартмани

03.05.2024    967    16    Hitcher    3    

10

Создать на основании - своя кнопка (БСП). Проблема двух подменю Создать на основании

БСП (Библиотека стандартных подсистем) Адаптация типовых решений Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Понадобилось в подменю "Создать на основании" добавить свою команду, которая открывает обработку. В процессе доработок появилась проблема двух подменю "Создать на основании". В статье о том, как решились проблемы.

01.03.2024    2792    dimanich70    8    

15

Заполнение поля адреса в своей обработке [БСП]

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

Небольшая шпаргалка по функциям БСП касательно адреса. Так скажем, еще один способ помимо https://infostart.ru/1c/articles/1060970/

12.02.2024    999    FilippovRI    0    

17

Расширяем возможности дополнительных обработок и настраиваем их отладку

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

Уже не одна веб-страница исписана знаниями о дополнительных обработках, как создать, как подключить. Есть масса вариантов, как их можно отладить. Я разобрался в кишках работы библиотеки и покажу, как можно расширить возможности дополнительных отчетов, а также покажу удобный способ отладки.

07.02.2024    3108    YA_418728146    11    

51

1С:БСП Дополнительные реквизиты и сведения

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

В этой статье расскажем об архитектуре, использовании и особенностях реализации подсистемы «Свойства» из инструментария разработчика «1С:Библиотека стандартных подсистем» (1С: БСП).

19.01.2024    9107    PROSTO-1C    5    

47
Отзывы
10. quazare 3704 03.04.22 18:04 Сейчас в теме
и еще момент - если хотите следить за моими новыми статьями БСП и не только - присоединяйтесь на мой канал телеграм
Остальные комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. ImHunter 318 01.04.22 15:14 Сейчас в теме
Спасибо огроменное! Как раз хотел в ближайшей перспективе экспериментировать с многопотоком от БСП. Вы мне немного времени сэкономили.
2. TheOldGuard 12 01.04.22 15:59 Сейчас в теме
Интересная статья, интересно раз это новый функционал, то какие подводные камни он в себе держит)
3. Totoro 569 01.04.22 16:48 Сейчас в теме
Если брать БСП, то это с БСП 3.1.6:
Новые возможности для разработчиков в версии 3.1.6
Базовая функциональность

Для ускорения выполнения длительных операций предусмотрена возможность выполнить обработчик длительной операции в несколько потоков. Для этого необходимо:
- Разделить данные на наборы, где каждый элемент набора будет обработан в отдельном фоновом задании.
- Из программного интерфейса общего модуля ДлительныеОперации для запуска процедуры длительной операции вызвать функцию ВыполнитьПроцедуруВНесколькоПотоков (или ВыполнитьФункциюВНесколькоПотоков), передав третьим параметром сформированный набор данных. Подробное описание параметров см. в комментарии к этим функциям.
- Максимально допустимое количество одновременно работающих фоновых заданий может быть задано администратором в разделе Администрирование - Общие настройки - Многопоточные длительные операции
- В файловой информационной базе и при работе в модели сервиса длительные операции всегда выполняются в один поток.
- Пример см. в демонстрационной конфигурации в форме ЗагрузкаАдресногоКлассификатора регистра сведений АдресныеОбъекты.
Angealtor; user1704444; mrChOP93; Dach; Gilev.Vyacheslav; JohnyDeath; Созинов; +7 Ответить
4. PowerBoy 3377 01.04.22 18:11 Сейчас в теме
Не увидел что здесь нового, и так можно было запустить фоновые задания в цикле со своим набором обработки данных, вот тебе и многопоток.
memfree; SerVer1C; quazare; mikl79; +4 Ответить
6. starik-2005 3050 01.04.22 23:23 Сейчас в теме
(4)
Не увидел что здесь нового
5 лет назад под такими статьями писали, что 1С не многопоточна, и что никакой прибавки к скорости не будет ))) Сейчас риторика поменялась, что-то в голове разработчиков подвинулось в нужную сторону. Видимо повлияло засилие процессоров с овер дофига ядер/потоков ))))
5. sanjabor 17 01.04.22 19:32 Сейчас в теме
Спасибо.

А никакой формы для визуализации прогресса многопоточной обработки не намечается? Только ПрочитатьПрогресс() и рисовать самому?
7. insurgut 207 02.04.22 17:58 Сейчас в теме
А профит есть? Не увидел в статье результатов сравнения производительности.
SlavaKron; DmitrichenkoInfoStart; +2 Ответить
13. ya.Avoronov 115 04.04.22 17:56 Сейчас в теме
(7) откуда появится разница, коли это старые рельсы, только параллельно?
8. qwed557 30 02.04.22 23:04 Сейчас в теме
А сколько созданных объектов показывает при создании справочника номенклатура? У вас подсчет количество созданных объектов за циклом идет.
9. quazare 3704 03.04.22 13:10 Сейчас в теме
Товарищи, всем задающим вопросы - далее я попробую развить эту тему в отдельной статье.

И да, основа подхода - это фоновое задание в «цикле»… в бсп, на мой взгляд - выполнено более красиво.
10. quazare 3704 03.04.22 18:04 Сейчас в теме
и еще момент - если хотите следить за моими новыми статьями БСП и не только - присоединяйтесь на мой канал телеграм
11. Jimbo 10 04.04.22 16:37 Сейчас в теме
В 2016-2017 сами писали на несколько потоков, например делили период год на месяцы и запрашивали по подразделениям, потом как все потоки завершатся - склеивали эти данные, полученные с каждого потока ТаблицуЗначений в один отчет
12. ya.Avoronov 115 04.04.22 17:53 Сейчас в теме
Каждый "даже не тру" разраб уже давным-давно сколхозил себе многопоточку.

ИМХО

* Перейдешь сейчас на новую БСП-шную, а она в новой версии БСП отвалится, как это и бывает подчас :(
* Кидаться и переписывать все под новый стандарт - пустая трата времени!
* Однако, конечно полезно изучить что-то новое!
maksa2005; +1 Ответить
14. pstrig 07.04.22 09:41 Сейчас в теме
Многопоточка? Интересно. Посмотрим
15. Риник 13 23.11.23 16:35 Сейчас в теме
На БСП версии 3.1.7.526 уже не сработает)

ПараметрыПотока должен быть массивом, а не структурой, красавцы 1С я считаю
16. quazare 3704 23.11.23 19:55 Сейчас в теме
(15) именно поэтому в том числе, я сделал актуализацию этих методов - обработкой

https://infostart.ru/1c/tools/1874539/
Оставьте свое сообщение