Я работаю над параллельными рабочими нагрузками, где каждый объект или задача сообщает о своем собственном прогрессе, и я хочу сообщить о коллективном прогрессе задачи в целом.
Например, представьте, что у меня есть 10 рабочих объектовкоторые все сообщают об индивидуальном прогрессе.Они содержат 0-100 «заданий», которые должны быть выполнены.
Если бы мы должны были линейно выполнять итерации по каждому из объектов Work, мы могли бы легко сообщить о нашем прогрессе и увидеть что-то вроде этого:
Work item #1 of 10 is currently 1 of 100 tasks completed.
Work item #1 of 10 is currently 2 of 100 tasks completed.
...
Work item #10 of 10 is currently 100 of 100 tasks completed.
Однако при параллельной работе вывод будет выглядеть примерно так:
Work item #1 of 10 is currently 1 of 100 tasks completed.
Work item #4 of 10 is currently 16 of 100 tasks completed.
Work item #7 of 10 is currently 4 of 100 tasks completed.
...
Work item #10 of 10 is currently 100 of 100 tasks completed.
Проблема, которую я пытаюсь решить, заключается в объединении всего процесса в параллельных циклах, так что вывод напользователь больше похож на «1/1000» или «10/1000», представляющий общий объем выполненной работы, и обновляющий числитель по мере продолжения работы.
Я ожидаю, что есть решение или шаблон, который подходит независимо от того,Async / Await или использование асинхронного шаблона задачи - я использую оба - и я надеюсь, что уже есть способы справиться с этим в .NET Framework, который я не обнаружил.
Использование этого простого (pseudocode) пример из TAP:
Parallel.ForEach(WorkObject, wo =>
{
// Perhaps each WorkObject has a "ProgressChanged" delegate that fires progress notifications.
wo.ProgressChanged += delegate (int currentProgress, int totalProgress)
{
ReportProgress($"Work item #{wo.ID} of {WorkObject.Count} is currently {currentProgress} of {totalProgress} tasks completed.
};
// Or perhaps using IProgress<T> or Progress?
// wo.PerformWork(/*IProgress<T> or Progress<T>, etc.*/);
});
Мы можем выполнять параллельные итерации, и обновления / уведомления о прогрессе будут поступать по завершении каждого потокаединица работы.
Как мы можем эффективно объединить прогресс всех WorkObjects так, чтобы мы могли сообщать о более равномерном "1/1000" выполненном?
Проблема в том, что каждый WorkObjectможет иметь разное количество «заданий» для выполнения, и у нас может быть разное количество WorkObjects, которые должны работать.Если просто объединить числитель и знаменатель из всех рабочих объектов при поступлении каждого уведомления о ходе выполнения (при условии, что они обновляются после завершения каждой единицы работы), к концу параллельной рабочей нагрузки уведомление о ходе выполнения будет отображать что-то вроде «1000/100 000».вместо «1000/1000».
Кажется, что нам нужен способ отслеживать текущий прогресс X, а также общий прогресс Y, чтобы сформировать связное сообщение для пользователя о состоянии общего прогресса(X of Y завершено.)
Существует ли существующая модель (в платформе или иным образом) для этого?
Моя текущая мысль - создать структуру данных, записывающую идентификатор потока каждогопоток выполняется параллельно, а затем отслеживает прогресс каждого потока в этом значении структуры данных (в виде X / Y) и, наконец, каждый поток публикует обновление прогресса, перебирая структуру данных для суммирования X / Y из каждого потока, чтобы сгенерироватьВсего "X / Y" для отображения пользователю.
Но, безусловно, эта проблемас разработчиками сталкиваются каждый день - значит, должен быть другой путь?