--- 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_ДлительныеОперации.ИзменитьРеквизитыНоменклатуры", ПараметрыВыполнения, НаборПараметровПроцедуры); КонецФункции ```