Многопоточность. Универсальный «Менеджер потоков» 2.0

Публикация № 778905

Администрирование - Оптимизация БД (HighLoad)

"Фоновые задания" потоки "менеджер потоков" фоновых заданий" распараллелить  "восстановление партий"  многопоточность 

156
Восстановление партий или взаиморасчетов, расчет зарплаты, пакетное формирование документов или отчетов - теперь все это стало доступнее. * Есть желание повысить скорость работы медленных алгоритмов! Но... * Нет времени думать о реализации многопоточности? * о запуске и остановке потоков? * о поддержании потоков в рабочем состоянии? * о передаче данных в потоки и как получить ответ из потока? * об организации последовательности? Тогда ЭТО - то что надо!!!
 
 Обновления
 
 Обновление "Менеджер потоков" 2.0.6

Изменения (возможно придется править события разработчика)

  • Данные рассчитываемые перед запуском нового потока теперь доступны в потоке(ах) по имени "ПараметрыРазработчикаПередЗапускомПотока" (до этого имя было: "ДанныеРарзаботчикаПередЗапускомПотока")
  • Данные рассчитываемые при запуске нового потока теперь доступны в потоке(ах) по имени "ПараметрыРазработчикаПриЗапускеПотока" (до этого имя было: "ДанныеРарзаботчикаПриЗапускеПотока")

Исправленные ошибки:

  • При работе с методом "ОбработатьОбъект" могла возникать ошибка (Спасибо Земко Сергей, за найденную ошибку):
    • {ОбщийМодуль.мпМенеджерПотоков.Модуль(1514)}: Поле объекта не обнаружено (АлгоритмыРаботыСКоллекцией)
    • КодСоздания = пСтруктураПараметров.ПараметрыИнициализации.ПараметрыОбработкиКоллекции.АлгоритмыРаботыСКоллекцией.КодСоздания;
  • Событие "ПослеЗавершенияМенеджераПотоков" теперь ВСЕГДА выполняется самым последним. Имели место случаи, когда данное событие вызывалось ДО события "ПередЗавершениемМенеджераПотоков".
  • Внесены корректировки в обработку коллекции без потоков (параметр определяется от объема коллекции и параметров инициализации):
    • Результат события "ПередЗапускомПотока", теперь доступны по имени "ПараметрыРазработчикаПередЗапускомПотока" (до этого имя было: "ДанныеДляПотока")
    • Добавлено выполнение события "ПриЗапускеПотока"
    • Добавлено выполнение события "ПриОбработкеМассиваОбработанныхФагментовКоллекции
    • Добавлено выполнение события "ПриОбработкеДополненногоФагментаКоллекции"
    • Исключено выполнение события "ПриОбработкеОбработанногоФагментаКоллекции"

                   P.S. Теперь обработка коллекции без потоков полностью имитирует вызов событий при работе в потоках.

Небольшая оптимизация:

  • Скорректированно ожидание "пустых" циклов с 1 сек. до 0.1 сек. (данные циклы исполняются для синхронизации работы фоновых заданий уже после полной обработки данных)
 
 Обновление "Менеджер потоков" 2.0.5
 
 Добавлена презентация с ISE 2018
 
 Другие статьи и разработки на данную тему:

Все, что было в первой версии, переработано, улучшено и дополнено. В связи с чем она (первая версия) переходит в разряд статьи с основными объяснениями и картинками.

Сразу договоримся, если в тексте будет указано «v1» - это отсылка к реализации в первой версии, если «v2» - к текущей.

Очень кратко, о чем речь…

Фреймворк в виде одного общего модуля, позволяющего при получении объектов на обработку запускать их в несколько потоков. Особенности:

  • Нет необходимости рассчитывать «порции» для обработки;
  • Нет необходимости организовывать файловый обмен между потоками;
  • Возможность запускать несколько менеджеров потоков одновременно, при этом потоки одного менеджера, могут запускать новые менеджеры со своими задачами и потоками;
  • Можно выстраивать граф зависимости объектов, что позволяет, например, избегать взаимоблокировок и/или организовать восстановление партий (на нашем предприятии удалось добиться 10х+ ускорения при 10 потоках в рабочее время – 200+ активных пользователей - Результаты работы механизма);
  • Все необходимые "вмешательство" в алгоритмы происходят с помощью событий;
  • Возможность описывать алгоритмы событий, как в модуле менеджера, так и в любом другом модуле БД (предпочтительно), а также во внешней обработке.
  • Автоматический рестарт потока в случае ошибок;
  • Контроль за количеством рестартов по каждому объекту;
  • Возможность получать «ответы» от потоков;
  • Возможность контролировать работу с помощью «Инструментов разработчика» или иных отчетов;
  • Возможность срочного прерывания работы;
  • И многое другое…

так было в «v1»

 

Основные изменения v2:

  • Только полная версия, полностью открытый код;
  • Практически полностью переписано ядро и архитектура (кода стало на ~50% больше), механизм обмена данными остался тот же (Хранилище общих настроек);
  • Появилось 3 способа обработки:
    • Обработка поэлементно:
      • Процедура ОбработатьОбъект(); (реализовано v1)
    • Обработка коллекций:
      • Процедура ОбработатьКоллекцию();
      • Процедура ДополнитьКоллекцию ().
  • Скорость обработки «зависимых» объектов происходит быстрее на 5-15% по сравнению с «v1», при выполнении одной и той же задачи;
  • Появилась возможность передавать в потоки произвольные единожды сформированные данные или рассчитывать их при запуске потока.
  • Возможность получать «ответ» об обработке объекта(ов) в «реальном времени» (в «v1» приходилось дополнительно прописывать обвязку из временного хранилища с помощью «СобытийРазработчика», откуда данные можно было получить только в конце обработки);
  • Сообщения выведенные в потоках, теперь выводятся автоматически (в «v1» приходилось обрабатывать через «Событиях разработчика»);
  • Расчет ресурсов теперь выполняют потоки;
  • Изменен состав «Событий разработчика»;
  • Изменена структура параметров передаваемых в «События разработчика»;
  • Граф теперь является одним объектом (в «v1» он состоял из нескольких не связанных объектов, что могло вызвать затруднения в понимании работы);
  • Расширены собираемые данные для анализа работы менеджера потоков (до 11 показателей);
  • Предоставлен шаблон функции «ОбработатьСобытиеРазработчика» для своих модулей;
  • В статью добавлены примеры;
  • Прочие мелочи.

Теперь обо всем по порядку в деталях и с картинками...

 
 
 Архитектура
 
 Способы обработки
 
 
 Параметры инициализации
 
 События разработчика
 
 Мониторинг
 
 Примеры работы и выводы

 

156

Менеджер потоков

Наименование Файл Версия Размер
Многопоточность. Универсальный «Менеджер потоков» 2.0 + Интерактивная остановка менеджеров потоков + Презентация ISE 2018:
.zip 3,84Mb
12.02.19
63
.zip 2.0.6 3,84Mb 63 Скачать

Обработки

Наименование Файл Версия Размер
Обработка с примерами из статьи
.epf 13,72Kb
12.02.19
30
.epf 13,72Kb 30 Скачать
Интерактивная остановка менеджеров потоков
.epf 10,67Kb
12.02.19
15
.epf 10,67Kb 15 Скачать

Все

Наименование Файл Версия Размер
Презентация ISE 2018
.pptx 4,06Mb
12.02.19
0
.pptx 4,06Mb Скачать

См. также

Специальные предложения

Лучшие комментарии
31. olegtymko 139 25.10.18 07:25 Сейчас в теме
Доклад на IE огонь!) Спасибо, потестирую у себя систему!
awk; drmaxart; +2 Ответить
Остальные комментарии
Избранное Подписка Сортировка: Древо
1. tormozit 5016 08.02.18 09:30 Сейчас в теме
Опечатка "ОбработатьКоллекуию"
6. DarkAn 774 08.02.18 13:03 Сейчас в теме
18. Evil Beaver 5472 08.02.18 18:09 Сейчас в теме
(6) Не везде. В примерах кода часто встречается.
19. DarkAn 774 08.02.18 19:58 Сейчас в теме
(18)видимо в спойлерах не ищет(( доберусь до компа перепроверю через "источник". В обработке поправлено, видимо пока готовил статью в Ворде не заметил). Спасибо.
2. Xershi 491 08.02.18 09:50 Сейчас в теме
Нужны реальные примеры для чего это нужно. Первую версию не читал.
7. DarkAn 774 08.02.18 13:05 Сейчас в теме
(2) Реальные примеры - чтоб у всех работало, придумать толком не смог :)
Идею можно посмотреть Тут
10. DarkAn 774 08.02.18 13:12 Сейчас в теме
(2)
чего это нужно
С помощью "ОбработатьОбъект" распараллелил партии в УПП Вот результаты
3. infosoft-v 296 08.02.18 10:04 Сейчас в теме
Здравствуйте. Мощная работа.
Проект есть на GitHub? Можно ссылку?
8. DarkAn 774 08.02.18 13:07 Сейчас в теме
(3) Нет нету :( Еще с ним не разобрался :(
4. dandykry 3 08.02.18 10:32 Сейчас в теме
Однозначный плюс за разработку.
5. tsukanov 69 08.02.18 10:54 Сейчас в теме
Эх. Вот сделали бы в платформе возможность ожидать завершения хотя бы одного задания из массива,
и все эти извраты были бы не нужны.
9. DarkAn 774 08.02.18 13:10 Сейчас в теме
(5) Ну так запускайте не в массиве, а по одному :) Массив то зачем?
11. tsukanov 69 08.02.18 13:24 Сейчас в теме
(9) А как ожидать завершения? По таймеру проверять?

Суть то в том, чтобы запустить пачку заданий и при завершении хотя бы одного тут же выдать новое задание с новой порцией данных. Так можно максимально утилизировать процессор и управление потоками становится тривиальным
12. DarkAn 774 08.02.18 13:25 Сейчас в теме
(11) Можно по таймеру, можно по значению переменной (в текущей реализации она также сохраняется в общих настройках) и мониторить ее на каждой итерации.
13. tsukanov 69 08.02.18 13:26 Сейчас в теме
(12) Вот вот. Извращения. А все из-за дурацкой реализации ожидания в платформе

ps Посмотрите в Go оператор Select - вот там правильно сделано
DarkAn; starik-2005; +2 Ответить
14. DarkAn 774 08.02.18 13:34 Сейчас в теме
(13) На сколько я понимаю, в Вашей реализации вы предлагаете задействовать, недавние вирусы (meltdown и spectre), тогда возможно получиться получать ответ сразу как задание выполнено :)
15. tsukanov 69 08.02.18 13:35 Сейчас в теме
(14) Не понял о чем вы. В общем смотрите как сделано в Go
28. tsukanov 69 07.09.18 08:10 Сейчас в теме
(14) Вышла 13 платформа, в которой это стало возможно )
29. DarkAn 774 07.09.18 10:49 Сейчас в теме
(28)
ышла 13 платформа, в которой это стало возмож

А можно по подробнее? На что обратить внимание?
30. tsukanov 69 07.09.18 14:01 Сейчас в теме
(29) Там новый метод для ожидания появился. Вот пример использования как я описывал выше: gist.github.com/tsukanov-as/4a75e731d959017d7238e5ce456e6f28

Ждем изменения статуса хотя бы одного и подменяем сразу на новое задание.
20. izidakg 143 08.02.18 22:54 Сейчас в теме
развитие будет или все задуманное реализовано?
22. DarkAn 774 09.02.18 09:06 Сейчас в теме
(20) Есть еще несколько идей (осталось только время найти для их воплощения). Они пока не реализованы, т.к. реализуй я их, то текущую версию выложил бы еще не скоро. Так основные задумки все работают - можно смело пользоваться.
21. artemka 09.02.18 07:59 Сейчас в теме
А каким образом происходит восстановление партий в несколько потоков? Например, для того, чтобы восстановить партию, мне нужно знать остатки по номенклатуре на дату, а пока предыдущий поток не завершится этих данных не будет.
23. DarkAn 774 09.02.18 09:09 Сейчас в теме
(21) Артем, для ответа на Ваш вопрос, я рекомендую Вам ознакомится первым постом и с текущим. В первом посте вообще все рассказывалось отталкиваясь именно от этой задачи.
Для простоты понимания посмотрите примеры из первого поста
24. gubanoff 45 09.02.18 10:42 Сейчас в теме
(0) на какой версии платформы можно использовать?
25. DarkAn 774 09.02.18 10:56 Сейчас в теме
(24) 8.2 и 8.3. v1 тестировалась на 1С:Предприятие 8.3 (8.3.9.1850) обычные формы. Примеры имеют и обычную, и управляемую формы.
26. kauksi 205 06.04.18 09:24 Сейчас в теме
У меня когда то была идея для РАУЗ... передать матрицу через внешнюю компоненту и быстренько посчитать все через CUDA... тока вот руки так и не дошли
27. kote 494 06.07.18 23:21 Сейчас в теме
(26)

.. знаю таких 2 в своей организации - это кроме себя :)

Кто об этом еще задумывался?
31. olegtymko 139 25.10.18 07:25 Сейчас в теме
Доклад на IE огонь!) Спасибо, потестирую у себя систему!
awk; drmaxart; +2 Ответить
32. DarkAn 774 25.10.18 09:36 Сейчас в теме
33. dimbasbear 39 28.01.19 10:46 Сейчас в теме
Добрый день, очень интересная статья, спасибо за труд.

Скажите:

1. Применимо для восстановление партий + оценка стоимости по средней ?
2. Можно краткий пример как это все запустить для п1, в частности как и у вас для конфигурации УПП.
34. DarkAn 774 28.01.19 17:18 Сейчас в теме
Добрый день!

(33)
Добрый день, очень интересная статья, спасибо за труд.

Спасибо за отзыв.


(33)
1. Применимо для восстановление партий + оценка стоимости по средней ?

Применимо для любого учета, кроме разве что - РАУЗ (хотя может и там сработает не проверял).
Все процедуры восстановления - ТИПОВЫЕ с небольшими оговорками о них ниже...

Что у нас есть в типовом учете:
1. У нас есть обработка "Проведение по партиям". В ней процедура "КнопкаВыполнитьНажатие", которая в свою очередь, так или иначе, вызывает "ЗаполнениеДокументов.ВыполнитьВосстановление".

2. В рамках этой процедуры обрабатывается последовательность документов и каждый документ последовательности обрабатывается с помощью "УправлениеЗапасамиПартионныйУчет.ДвижениеПартийТоваров(..." (по крайне мере основная масса документов списания).

Все, что необходимо сделать - это чтобы эта строка кода выполнялась в событии "ПриОбработкеДействияПотока" со всеми своими параметрами

для этого необходимо следующее:
1. Перед началом цикла "Пока ЕстьДокументы Цикл" получить параметры менеджера потоков, установить параметры и провести его инициализацию
2. В цикле вместо "УправлениеЗапасамиПартионныйУчет.ДвижениеПартийТоваров (..." вызвать метод менеджера потоков "ОбработатьОбъект", куда параметрами передать а) СтруктуруПараметровМенеджера, б) ссылку на документ в) Структуру (или любую другой коллекцию) со всеми параметрами из типовой "УправлениеЗапасамиПартионныйУчет.ДвижениеПартийТоваров (..."
3. После цикла вызвать метод "ДождатьсяОстановкиМенеджераПотоков" куда передать только СтруктуруПараметровМенеджера.
Все больше в типовой обработке ни чего править не надо.

Дальше идет работа с событиями, что использовалось у Нас:
1. "ПередЗапускомМенеджераПотоков" Создали массив(пустую) для учета документов восстановление по которым не получилось;
2. "ПриПолученииРесурсов" Это основное событие распараллеливания - тут по каждому документу необходимо собирать его ресурсы. Как? Смотрите примеры из презентации или статьи
3. "ПриДобавленииВОчередьОбработки" - тут все просто, если ресурсы есть - возвращаем "Истина", если их нет - "Ложь". Кода возвращается "Истина", объект помещается в граф и по нему рассчитываются связи в зависимости от ресурсов (следующее событие "ПриОбработкеДействияПотока"), а если "Ложь", то объект - пропускается (следующее событие "ПриОбработкеПропуска")
4. "ПриОбработкеДействияПотока" собственно вызываем нашу строчку кода "УправлениеЗапасамиПартионныйУчет.ДвижениеПартийТоваров(..." со всеми параметрами. Результатом данного метода могут быть произвольные данные (ловятся в событии "ПриОбработкеОтвета")

5. Надо зафиксировать факт НЕ обработки объекта - это можно сделать в 2х событиях: "ПриОбработкеОшибки" - если поток падал в момент обработки объекта (по умолчанию до 5 раз пытается обработать объект) и в событии "ПриОбработкеОтвета" можно, например, при обработке события "ПриОбработкеДействияПотока" возвращать значение переменной "Отказ" если оно "Истина", в этом случае мы заносим объект в структуру определенную в п1.

6. "ПослеЗавершенияМенеджераПотоков" собственно - это последнее событие в нем мы производим установку границы последовательности. Если массив из п1 - пуст, то на самый последний документ последовательности в периоде, а если в массиве есть хоть один документ, то границу устанавливаем на самый ранний.


Для примера:
Количество строк кода во всех событиях: ~400
Самое большое событие: "ПриПолученииРесурсов" ~ 150 строк
Самое маленькое событие: "ПриДобавленииВОчередьОбработки" - 1 строка (Возврат пПараметрыСобытия.СтруктураДанных.МассивРесурсов.Количество() > 0;)

P.S. Один из не маловажных моментов :)
Код написанный в цикле процедуры "ВыполнитьВосстановление" - выполняется в транзакции, так вот: перед выполнением метода "ОбработатьОбъект" рекомендуется ее зафиксировать, а сразу за ним Начать новую. Кроме того в событии "ПриОбработкеДействияПотока" строку "УправлениеЗапасамиПартионныйУчет.ДвижениеПартийТоваров(..." - наоборот заключить в транзакцию
P.P.S. У нас помимо "УправлениеЗапасамиПартионныйУчет.ДвижениеПартийТоваров(..." в событии "ПриОбработкеДействияПотока" вызывается еще и "УправлениеПроизводствомДвиженияПоРегистрам.ПровестиДокументПоПроизводственнымРегистрам(..."

Но так у Нас, у Вас возможно будет по другому :)
35. velsevur 29.01.19 09:10 Сейчас в теме
(34)
2. "ПриПолученииРесурсов" Это основное событие распараллеливания - тут по каждому документу необходимо собирать его ресурсы. Как? Смотрите примеры из презентации или статьи


Доброго дня.
А можно привести пример кода для формирования ресурса и как потом им пользоваться. Я в этом месте застрял.
36. DarkAn 774 29.01.19 10:38 Сейчас в теме
(35)
А можно привести пример кода для формирования ресурса и как потом им пользоваться.


Ресурсами ни как пользоваться не надо ими пользуется "менеджер потоков" главное правильно их сформировать (тут пример в примерах, на картинках, см. строку "Массивы" надо сформировать массив массивов)

Вот примерный код:
СтруктураДанных = пПараметрыСобытия.СтруктураДанных;
ОбрабатываемыйОбъект = СтруктураДанных.ОбрабатываемыйОбъект;
ПараметрыДляОбъекта  = СтруктураДанных.ПараметрыДляОбъекта;

МассивРесурсов = Новый Массив;
ТаблицаСписания = УправлениеЗапасамиПартионныйУчет.ПолучитьТаблицуСтрокДокументов(ОбрабатываемыйОбъект, 
				ПараметрыДляОбъекта.Упр, 
				ПараметрыДляОбъекта.Бух, 
				ПараметрыДляОбъекта.Нал);	
	
Для каждого СтрокаСписания из ТаблицаСписания Цикл
	МассивРесурса  = Новый Массив;
	МассивРесурса.Добавить(СтрокаСписания.Номенклатура);
	МассивРесурса.Добавить(СтрокаСписания.Склад);
		
	МассивРесурсов.Добавить(МассивРесурса);
КонецЦикла;

Возврат МассивРесурсов;
Показать
37. dimbasbear 39 29.01.19 16:11 Сейчас в теме
Дальше идет работа с событиями, что использовалось у Нас:
1. "ПередЗапускомМенеджераПотоков" Создали массив(пустую) для учета документов восстановление по которым не получилось;
2. "ПриПолученииРесурсов" Это основное событие распараллеливания - тут по каждому документу необходимо собирать его ресурсы. Как? Смотрите примеры из презентации или статьи
3. "ПриДобавленииВОчередьОбработки" - тут все просто, если ресурсы есть - возвращаем "Истина", если их нет - "Ложь". Кода возвращается "Истина", объект помещается в граф и по нему рассчитываются связи в зависимости от ресурсов (следующее событие "ПриОбработкеДействияПотока"), а если "Ложь", то объект - пропускается (следующее событие "ПриОбработкеПропуска")
4. "ПриОбработкеДействияПотока" собственно вызываем нашу строчку кода "УправлениеЗапасамиПартионныйУчет.ДвижениеПартийТоваров(..." со всеми параметрами. Результатом данного метода могут быть произвольные данные (ловятся в событии "ПриОбработкеОтвета")

5. Надо зафиксировать факт НЕ обработки объекта - это можно сделать в 2х событиях: "ПриОбработкеОшибки" - если поток падал в момент обработки объекта (по умолчанию до 5 раз пытается обработать объект) и в событии "ПриОбработкеОтвета" можно, например, при обработке события "ПриОбработкеДействияПотока" возвращать значение переменной "Отказ" если оно "Истина", в этом случае мы заносим объект в структуру определенную в п1.

6. "ПослеЗавершенияМенеджераПотоков" собственно - это последнее событие в нем мы производим установку границы последовательности. Если массив из п1 - пуст, то на самый последний документ последовательности в периоде, а если в массиве есть хоть один документ, то границу устанавливаем на самый ранний.


Дошел до событий, дабы не городить костыли - можно пример кода по каждому из событий для восст. по партиям?
38. DarkAn 774 29.01.19 17:14 Сейчас в теме
(37)
Дошел до событий, дабы не городить костыли - можно пример кода по каждому из событий для восст. по партиям?


В рамках данной статьи это не предусмотрено.
Постараюсь собраться с силами и выложить новую со всеми кодами для восстановления партий на нашем примере :)

Вам могу, пока, посоветовать "городить костыли" заодно опробуете все сами.

Рекомендации:
0) Поднимите копию базы и сделайте там первое полное восстановление за месяц (это будет эталон для сравнения)
1) разработку рекомендую начать в отдельной базе с 1 потока;
2) восстановление делайте в рамках 1 дня;
3) для сверки пользуйтесь "Ведомость по партиям товаров на складах"
4) как добьетесь результата на 1 потоке увеличивайте их количество до 2-3, если и на них все будет гладко, то ставьте, то количество которое потянет ваш сервер :) (У нас восстановление делается на 10 потоках - этого для нас достаточно. Но была задача по непосредственному удалению документов из БД, там писали обработку и удаляли на 45 потоках. Все зависит от специфики, задачи, железа и т.д.)

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

Так что, дерзайте!

P.S. Я надеюсь у Вас управляемый режим блокировок?
39. velsevur 30.01.19 10:59 Сейчас в теме
Подскажите, что нужно сделать, что-бы сработал механизм формирования ресурсов.
Запускаю потоки через "мпМенеджерПотоков.ОбработатьКоллекциюОбъектов".

2. "ПриПолученииРесурсов" Это основное событие распараллеливания - тут по каждому документу необходимо собирать его ресурсы. Как? Смотрите примеры из презентации или статьи
не срабатывает.
40. DarkAn 774 30.01.19 11:13 Сейчас в теме
Событие "ПриПолученииРесурсов" предназначено только для метода "ОбработатьОбъект" - когда по объектам необходимо строить граф.
Рекомендую посмотреть презентацию с IE2018 (ссылка есть в публикации) или тут.
Необходимый минимум для метода "ОбработатьКоллекциюОбъектов" показан тут.

Пока прикладываю схему доступности событий от методов
Прикрепленные файлы:
41. velsevur 01.02.19 12:09 Сейчас в теме
(40) Спасибо.

Подскажите что я делаю не так:
1. Получаю параметры "ПолучитьСтруктуруПараметровИнициализацииМенеджераПотоков"
2. Инициализирую МП "ИнициализироватьМенеджерПотоков"
3. В цикле обхожу выборку документов методом "ОбработатьОбъект"
4. После цикла ожидаю завершения МП "ДождатьсяОстановкиМенеджераПотоков"

Получаю ошибку:
Поле объекта не обнаружено (АлгоритмыРаботыСКоллекцией)
КодСоздания   = пСтруктураПараметров.ПараметрыИнициализации.ПараметрыОбработкиКоллекции.АлгоритмыРаботыСКоллекцией.КодСоздания;


В структуре "ПараметрыОбработкиКоллекции" действительно нет "АлгоритмыРаботыСКоллекцией".

Перед циклом дописал:
КодСоздания   = "КоллекцияПриемник = Новый СписокЗначений;";
		КодДобавления = "ЗаполнитьЗначенияСвойств(КоллекцияПриемник.Добавить(), КоллекцияИсточник[ИндексКоллекции]);";

		Структура = Новый Структура;
		Структура.Вставить("КодСоздания"  , КодСоздания);
		Структура.Вставить("КодДобавления", КодДобавления);
		
		СтруктураПараметромМП.ПараметрыИнициализации.ПараметрыОбработкиКоллекции.Вставить("АлгоритмыРаботыСКоллекцией", Структура);


А как нужно было сделать правильно?
42. DarkAn 774 01.02.19 13:06 Сейчас в теме
(41) пункты с 1 по 4 - правильные
Но вот код вызывающий у Вас ошибку срабатывать не должен. Он относится к методам работы с коллекциями.
И встречается в 2х местах:
Функция ПолучитьДанныеИзМенеджераПотоков 
...
ИначеЕсли РезультатОбработки = "ДополненныйФрагментКоллекции" Тогда
...

и
Функция ОбработатьКоллекцию

которая в свою очередь вызывается из метода "ОбработатьКоллекциюОбъектов" и "ДополнитьКоллекциюОбъектов"


Версия менеджера у Вас 2.0.5? (не могу определить дату скачивания - не вижу Вас среди скачавших)

Можете мне прислать замер производительности по работе ФЗ "менеджера потоков"? (например через вотсап - номер в профиле)
и Код используемой обработки или саму обработку.
43. velsevur 01.02.19 14:07 Сейчас в теме
(42) Не вижу номера в профиле, возможно нужно быть в друзьях. Версия 2.0.5. Скачивался МП с другого аккаунта "Cruciann".

		Сообщить("Обработка в потоках.");
		ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
		
		СтруктураПараметров = векМенеджерПотоков.ПолучитьСтруктуруПараметровИнициализацииМенеджераПотоков("ОбработатьКоллекциюДокументовОчередипереобеспечения","");
		векМодульМенеджераПотоков.ПолучитьПараметрыМП("ЗаказПоставщику",СтруктураПараметров);
		СтруктураПараметромМП = векМенеджерПотоков.ИнициализироватьМенеджерПотоков(СтруктураПараметров);
		
#Область Костыли
		КодСоздания   = "КоллекцияПриемник = Новый СписокЗначений;";
		КодДобавления = "ЗаполнитьЗначенияСвойств(КоллекцияПриемник.Добавить(), КоллекцияИсточник[ИндексКоллекции]);";

		Структура = Новый Структура;
		Структура.Вставить("КодСоздания"  , КодСоздания);
		Структура.Вставить("КодДобавления", КодДобавления);
		
		СтруктураПараметромМП.ПараметрыИнициализации.ПараметрыОбработкиКоллекции.Вставить("АлгоритмыРаботыСКоллекцией", Структура);
#КонецОбласти

		Для Каждого ДокументСсылка Из Коллекция Цикл 
			СтруктурапараметровОбъекта = Новый Структура;
			СтруктурапараметровОбъекта.Вставить("Период",ДокументСсылка.Период);
			
			векМенеджерПотоков.ОбработатьОбъект(СтруктураПараметромМП,ДокументСсылка.Документ,СтруктурапараметровОбъекта);
		КонецЦикла;
		векМенеджерПотоков.ДождатьсяОстановкиМенеджераПотоков(СтруктураПараметромМП);
		
		ВремяКонцаВыполнения = ТекущаяУниверсальнаяДатаВМиллисекундах();
		ВремяВыполненияВМиллисекундах = ВремяКонцаВыполнения - ВремяНачала;
		Сообщить("Окончание потоковой обработки: "+ВремяВыполненияВМиллисекундах / 1000);
Показать



Процедура ПолучитьПараметрыМП(ОбъектОбработки,СтруктураПараметров) Экспорт 
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	векНастройкиМногопоточности.МодульОбработкиСобытийРазработчика КАК МодульОбработкиСобытийРазработчика,
	|	векНастройкиМногопоточности.МинимальноеКоличествоКоллекции КАК МинимальноеКоличествоКоллекции,
	|	векНастройкиМногопоточности.КоличествоПотоков КАК КоличествоПотоков,
	|	векНастройкиМногопоточности.КоличествоЭлементовКолекцииНаПоток КАК КоличествоЭлементовКолекцииНаПоток,
	|	векНастройкиМногопоточности.КоэффициентКратностиОчередиПотоковКПотокам КАК КоэффициентКратностиОчередиПотоковКПотокам,
	|	векНастройкиМногопоточности.ПределКоличествоПопытокОбработатьОбъект КАК ПределКоличествоПопытокОбработатьОбъект
	|ИЗ
	|	РегистрСведений.векНастройкиМногопоточности КАК векНастройкиМногопоточности
	|ГДЕ
	|	векНастройкиМногопоточности.Активно
	|	И векНастройкиМногопоточности.ОбъектОбработки = &ОбъектОбработки";
	
	Запрос.УстановитьПараметр("ОбъектОбработки", ОбъектОбработки);
	
	РезультатЗапроса = Запрос.Выполнить();
	Выборка = РезультатЗапроса.Выбрать();
	
	СтруктураПараметров.ПараметрыОбщие.Вставить("Активно",Ложь);
	
	Если Выборка.Следующий() Тогда
		
		Если ЗначениеЗаполнено(Выборка.МодульОбработкиСобытийРазработчика) Тогда 
			СтруктураПараметров.ПараметрыИнициализации.МодульОбработкиСобытийРазработчика = Выборка.МодульОбработкиСобытийРазработчика;
		КонецЕсли;
		
		Если ЗначениеЗаполнено(Выборка.КоличествоПотоков) Тогда 
			Если ТипЗнч(Выборка.КоличествоПотоков) = Тип("Число") Тогда 
				СтруктураПараметров.ПараметрыИнициализации.КоличествоПотоков = Выборка.КоличествоПотоков;
			КонецЕсли;
			
			Если ТипЗнч(Выборка.КоличествоПотоков) = Тип("Булево") Тогда 
				СтруктураПараметров.ПараметрыИнициализации.ПараметрыОбработкиКоллекции.ДинамическийРассчетКоличестваПотоков = Выборка.КоличествоПотоков;
			КонецЕсли;
		КонецЕсли;
		
		Если ЗначениеЗаполнено(Выборка.КоличествоЭлементовКолекцииНаПоток) Тогда 
			СтруктураПараметров.ПараметрыИнициализации.ПараметрыОбработкиКоллекции.КоличествоЭлементовКолекцииНаПоток = Выборка.КоличествоЭлементовКолекцииНаПоток;
		КонецЕсли;
		
		Если ЗначениеЗаполнено(Выборка.КоэффициентКратностиОчередиПотоковКПотокам) Тогда 
			СтруктураПараметров.ПараметрыИнициализации.КоэффициентКратностиОчередиПотоковКПотокам = Выборка.КоэффициентКратностиОчередиПотоковКПотокам;
		КонецЕсли;
		
		Если ЗначениеЗаполнено(Выборка.ПределКоличествоПопытокОбработатьОбъект) Тогда 
			СтруктураПараметров.ПараметрыИнициализации.ПределКоличествоПопытокОбработатьОбъект = Выборка.ПределКоличествоПопытокОбработатьОбъект;
		КонецЕсли;
		
		СтруктураПараметров.ПараметрыОбщие.Активно = Истина;
		СтруктураПараметров.ПараметрыОбщие.Вставить("МинимальноеКоличествоКоллекции",Макс(Выборка.МинимальноеКоличествоКоллекции,1));
		
	КонецЕсли;
	
КонецПроцедуры
Показать


Если ИмяСобытия = "ПриПолученииРесурсов" Тогда				//Поток
			
			ОтветСобытия = ПриПолученииРесурсов(пПараметрыСобытия);
			//Сообщение = Новый СообщениеПользователю;
			//Сообщение.Текст = "Ресурс получен";
			//Сообщение.Сообщить();
		
		ИначеЕсли ИмяСобытия = "ПриОбработкеДействияПотока" Тогда		//Поток
			СтруктураДанных = пПараметрыСобытия.СтруктураДанных;
			ПараметрыДляОбъекта = СтруктураДанных.ПараметрыДляОбъекта;
			
			РегистрыСведений.векОчередьДляПереобеспечения.ОбработатьДокумент(ПараметрыДляОбъекта.Период, СтруктураДанных.ОбрабатываемыйОбъект);
Показать


Функция ПриПолученииРесурсов(пПараметрыСобытия)
	
	СтруктураДанных = пПараметрыСобытия.СтруктураДанных;
	ОбрабатываемыйОбъект = СтруктураДанных.ОбрабатываемыйОбъект;
	
	ТабличнаяЧастьДокумента = ПолучитьТабличнуюЧастьДокумента(ОбрабатываемыйОбъект);
	
	МассивРесурсов = Новый Массив;
	МассивРесурса  = Новый Массив;
	МассивРесурса.Добавить(векПолучитьЗначениеРеквизита(ОбрабатываемыйОбъект,"Склад"));
	
	Для каждого СтрокаТЧД из ТабличнаяЧастьДокумента Цикл
		МассивРесурса.Добавить(СтрокаТЧД.Номенклатура);
	КонецЦикла;
	
	МассивРесурсов.Добавить(МассивРесурса);
	
	Возврат МассивРесурсов;
	
КонецФункции
Показать
Прикрепленные файлы:
44. velsevur 01.02.19 16:15 Сейчас в теме
(43)
Благодаря помощи автора темы проблема была решена путем правки модуля МП,

Строки с 1514-1516 необходимо обернуть в условие

Если РезультатОбработки = "ДополненныйФрагментКоллекции" Тогда


Спасибо DarkAn
Оставьте свое сообщение