1

我正在尝试运行两组并行任务。我的 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 组仍在运行时,函数会退出。

我想我可以重写它,以便它们都可以互操作,可能通过使用任务集合的并行循环的并行循环,但这会对 clr 内的线程管理等产生一些不利影响吗?

背景是我有一个间隔运行的后台进程,我将它运行的任务分成两组,A组是几个长时间运行的任务,B组是一系列存储在队列中的短期运行任务。两组具有相同的优先级,具有相同的开始和停止时间,队列可以在时间到时停止,任何任务都可以重新启动下一个周期。

4

1 回答 1

3

你可以使用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 接口并且很难推断发生了什么

于 2018-10-24T06:41:02.380 回答