Skip to content

Длительная многопоточная операция

Определение длительной операции

Многопоточные операции применяются в случаях обработки большого массива данных — например, для изменения реквизитов номенклатуры, обработки больших табличных документов, массового добавления объектов и пр. В типовых конфигурациях есть механизм для создания операций, выполняющихся в нескольких потоках — этот механизм определен в общих модулях «Длительные операции» Для примера возьмем алгоритм, изменяющий реквизиты объектов справочника Номенклатура. Реализуем в общем модуле процедуру, которая будет вызываться в многопоточном режиме:

Процедура ИзменитьРеквизитыНоменклатуры(НаборЗаписей) Экспорт
Если Не Пользователи.ЭтоПолноправныйПользователь(Пользователи.ТекущийПользователь()) Тогда
ТекстСообщения = "Это действие может выполнить только администратор";
ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
Возврат;
КонецЕсли;
Для Каждого Элемент Из НаборЗаписей Цикл
Об = Элемент.Номенклатура.ПолучитьОбъект();
Если Об.Заблокирован() Тогда
Продолжить;
КонецЕсли;
Попытка
Об.Заблокировать();
Исключение
ТекстСообщения = СтрШаблон("Не удалось изменить %1. Объект заблокирован", Элемент.Номенклатура);
ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
Продолжить;
КонецПопытки;
Об.ИспользоватьУпаковки = Истина;
Об.НаборУпаковок = Элемент.НаборУпаковок;
Попытка
Об.Записать();
Исключение
ТекстСообщения = СтрШаблон("Не удалось изменить %1. Ошибка записи объекта", Элемент.Номенклатура);
ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
Продолжить;
КонецПопытки;
КонецЦикла;
КонецПроцедуры

Определение клиентских вызовов

image.png Команда «Установить новый набор» выполняет разделение строк ТЧ на равные порции, т.е. создает список наборов, которые будут передаваться в процедуру из шага 1 (Функция «СписокНаборовДанныхДляДлительнойОперации«). Дополнительно инициализируются настройки ожидания и параметры выполняемой процедуры (Функция «ДлительныеОперации«). Также указывается процедура, которая будет выполнена после завершения всех потоков длительной операции

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

В функции длительная операция необходимо правильно сформировать параметры для метода ДлительныеОперации.ВыполнитьПроцедуруВНесколькоПотоков. Первым аргументом передаем полное имя экспортного метода, который нужно выполнять, вторым — структуру ДлительныеОперации.ПараметрыВыполненияВФоне, а третьим — правильно оформленный набор параметров.

Набор параметров — это соответствие, ключ — произвольный тип, значение — МАССИВ параметров, которые нужно передать в вызываемый метод. Количество параметров — до 7 шт. В примере метод «ИзменитьРеквизитыНоменклатуры» принимает только один параметр, соответственно в значение записи набора параметров мы передаем обернутое в массив значение параметра («ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Набор)»)

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