---
title: Длительная многопоточная операция
slug: примеры-сниппеты-бсп-и-типовые-длительные-операции-и-выполнение-в-фоне/длительная-многопоточная-операция
---
# Определение длительной операции
Многопоточные операции применяются в случаях обработки большого массива данных — например, для изменения реквизитов номенклатуры, обработки больших табличных документов, массового добавления объектов и пр.
В типовых конфигурациях есть механизм для создания операций, выполняющихся в нескольких потоках — этот механизм определен в общих модулях `«Длительные операции»`
Для примера возьмем алгоритм, изменяющий реквизиты объектов справочника `Номенклатура`. Реализуем в общем модуле процедуру, которая будет вызываться в многопоточном режиме:
```bsl
Процедура ИзменитьРеквизитыНоменклатуры(НаборЗаписей) Экспорт
 
	Если Не Пользователи.ЭтоПолноправныйПользователь(Пользователи.ТекущийПользователь()) Тогда
		ТекстСообщения = "Это действие может выполнить только администратор";
		ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
		Возврат;
	КонецЕсли;
	
	Для Каждого Элемент Из НаборЗаписей Цикл
		
		Об = Элемент.Номенклатура.ПолучитьОбъект();
		Если Об.Заблокирован() Тогда
			Продолжить;
		КонецЕсли;
		
		Попытка 
			Об.Заблокировать();
		Исключение
			ТекстСообщения = СтрШаблон("Не удалось изменить %1. Объект заблокирован", Элемент.Номенклатура);
			ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
			Продолжить;
		КонецПопытки;
		
		Об.ИспользоватьУпаковки = Истина;
		Об.НаборУпаковок = Элемент.НаборУпаковок;
		Попытка
			Об.Записать();
		Исключение
			ТекстСообщения = СтрШаблон("Не удалось изменить %1. Ошибка записи объекта", Элемент.Номенклатура);
			ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
			Продолжить;
		КонецПопытки;
		
	КонецЦикла;
	
КонецПроцедуры
```

# Определение клиентских вызовов
![image.png](https://sinenikolsky.ru/s/QEWSKmHn7HKGJX4/download?path=%2F2025%2F04%2F16&files=0f68e5a7-bd92-4e6a-9d6b-4972c5ed1f44.png)
Команда `«Установить новый набор»` выполняет разделение строк ТЧ на равные порции, т.е. создает список наборов, которые будут передаваться в процедуру из шага 1 (Функция `«СписокНаборовДанныхДляДлительнойОперации«`). Дополнительно инициализируются настройки ожидания и параметры выполняемой процедуры (Функция `«ДлительныеОперации«`). Также указывается процедура, которая будет выполнена после завершения всех потоков длительной операции
```bsl
&НаКлиенте
Процедура УстановитьНовыйНабор(Команда)
	
	ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	ПараметрыОжидания.ВыводитьОкноОжидания = Истина;
	ПараметрыОжидания.ВыводитьСообщения = Истина;
	ПараметрыОжидания.ОповещениеПользователя.Показать = Истина;
	
	СписокНаборов = СписокНаборовДанныхДляДлительнойОперации();
	
	МногопоточнаяОперация = ДлительнаяОперация(УникальныйИдентификатор, СписокНаборов);
	
	ОписаниеОповещения = Новый ОписаниеОповещения("ВыполнитьПоЗавершениюМногопоточнойОперации", ЭтотОбъект);
	
	ДлительныеОперацииКлиент.ОжидатьЗавершение(МногопоточнаяОперация, ОписаниеОповещения, ПараметрыОжидания); 
	
КонецПроцедуры
 
&НаКлиенте
Функция СписокНаборовДанныхДляДлительнойОперации()
 
	НаборЗаписей = Новый Массив;
	
	КоличествоЗаписейНаПоток = Цел(Объект.СписокНоменклатуры.Количество() / КоличествоПотоков) + 1;
	
	СписокНаборов = Новый Массив;
	
	Сч = 1;
	Для Каждого Строка Из Объект.СписокНоменклатуры Цикл
		
		Если Не Строка.НовыйИспользоватьУпаковки Тогда
			Сообщить("Не добавлена строка " + Строка.НомерСтроки);
			Продолжить;
		КонецЕсли;
		
		ПараметрыСтроки = Новый Структура;
		ПараметрыСтроки.Вставить("Номенклатура", Строка.Номенклатура);
		ПараметрыСтроки.Вставить("ИспользоватьУпаковки", Истина);
		ПараметрыСтроки.Вставить("НаборУпаковок", Строка.НовыйНаборУпаковок);
		
		НаборЗаписей.Добавить(ПараметрыСтроки);
		Сч = Сч + 1;
		НужноДобавитьНабор = Истина;
		
		Если Сч % КоличествоЗаписейНаПоток = 0 Тогда
			СписокНаборов.Добавить(НаборЗаписей);
			НаборЗаписей = Новый Массив;
			НужноДобавитьНабор = Ложь;
		КонецЕсли;
		
	КонецЦикла;
	
	Если НужноДобавитьНабор Тогда
		СписокНаборов.Добавить(НаборЗаписей);
	КонецЕсли;
	
	КоличествоЗаписей = 0;
	
	Для Каждого Массив Из СписокНаборов Цикл
		
		КоличествоЗаписей = КоличествоЗаписей + Массив.Количество();
		
	КонецЦикла;	
	
	Возврат СписокНаборов;
	
КонецФункции
 
&НаКлиенте
Процедура ВыполнитьПоЗавершениюМногопоточнойОперации(Задание, ДополнительныеПараметры) Экспорт
	
	Если Задание = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Сообщить(Задание.Статус);
 
КонецПроцедуры
```
В функции длительная операция необходимо правильно сформировать параметры для метода `ДлительныеОперации.ВыполнитьПроцедуруВНесколькоПотоков`. Первым аргументом передаем полное имя экспортного метода, который нужно выполнять, вторым — структуру `ДлительныеОперации.ПараметрыВыполненияВФоне`, а третьим — правильно оформленный набор параметров.

**Набор параметров** — это соответствие, ключ — произвольный тип, значение — МАССИВ параметров, которые нужно передать в вызываемый метод. Количество параметров — **до 7 шт**. В примере метод `«ИзменитьРеквизитыНоменклатуры»` принимает только один параметр, соответственно в значение записи набора параметров мы передаем обернутое в массив значение параметра (`«ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Набор)»`)
```bsl
&НаСервере
Функция ДлительнаяОперация(УИД, СписокНаборовДанных)
 
	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УИД);
	ПараметрыВыполнения.НаименованиеФоновогоЗадания = "Многопоточное изменение реквизитов номенклатуры";
	ПараметрыВыполнения.ЗапуститьВФоне = Истина;
	
	Сч = 1;
	НаборПараметровПроцедуры = Новый Соответствие;
	Для Каждого Набор Из СписокНаборовДанных Цикл
		НаборПараметровПроцедуры.Вставить("Набор №" + Сч, ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Набор));
		Сч = Сч + 1;
	КонецЦикла;
	
	Возврат ДлительныеОперации.ВыполнитьПроцедуруВНесколькоПотоков(
		"Расш1_ДлительныеОперации.ИзменитьРеквизитыНоменклатуры", 
		ПараметрыВыполнения, НаборПараметровПроцедуры);
	
КонецФункции
```