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