c # - запуск нескольких наборов параллельных потоков (Parallel.ForEach) - PullRequest
0 голосов
/ 24 октября 2018

Я пытаюсь запустить два набора параллельных задач.мой метод task.Invoke () является асинхронным, поэтому в первом наборе задач я опускаю .Wait ();но во втором наборе я использую .Wait (), поэтому он не выйдет из параллельного набора, пока все задачи не будут фактически выполнены.

Как правило, это работает в том случае, если задачи группы A запускаются, а затем запускаются задачи группы B, все задачи работают параллельно в пределах их группы с запущенной группой A, выполняется группа B, и группа b не завершается, пока всезадачи его задачи выполнены.

            var parallelA = new List<IMyTask>();
            parallelA.Add(new MyTask());
            parallelA.Add(new MyTask());

            await Task.Run(() => Parallel.ForEach(parallelA, task =>
            {
                task.Invoke();
            }));

            var parallelB = new List<IMyTask>();
            parallelB.Add(new MyTask());
            parallelB.Add(new MyTask());

            await Task.Run(() => Parallel.ForEach(parallelB, task =>
            {
                task.Invoke().Wait();
            }));

Проблема заключается в том, что группа задач не обязательно завершается до того, как группа задач b будет выполнена, поэтому функция завершается, пока группа a все еще работает в некоторых случаях.

Я полагаю, я мог бы переписать его так, чтобы все они взаимодействовали, возможно, с помощью параллельного цикла параллельных циклов с использованием набора задач, но это может оказать некоторое негативное влияние на управление потоками,и т.д. внутри клр?

Фоном является то, что у меня есть фоновый процесс, который выполняется с интервалом, я разбиваю задачи, которые он выполняет, на две группы, группа A - это пара долгосрочных задач, а группа B - серия краткосрочных задач.хранится в очереди.Оба набора имеют одинаковый приоритет с одинаковым временем запуска и остановки, причем очередь можно просто остановить, когда истечет время, и любые задачи могут быть перезапущены в следующем цикле.

1 Ответ

0 голосов
/ 24 октября 2018

Вы можете просто использовать WhenAll

var parallelA = new List<IMyTask>();
parallelA.Add(new MyTask());
parallelA.Add(new MyTask());

var task1 = Task.Run(() => Parallel.ForEach(parallelA, task =>
   {
      task.Invoke();
   }));

var parallelB = new List<IMyTask>();
parallelB.Add(new MyTask());
parallelB.Add(new MyTask());

var task2 = Task.Run(() => Parallel.ForEach(parallelB, task =>
   {
      task.Invoke().Wait();
   }));

await Task.WhenAll(task1, task2);

Примечание , возможно, есть и лучшие способы сделать это, вы можете просто использовать списки задач и не использовать Parallel.ForEachВ общем, хотя вы используете интерфейс IMyTask и его трудно определить, что происходит

...