并行执行一对任务

本文关键字:任务 并行执行 | 更新日期: 2023-09-27 18:07:14

有两个执行On/Off的任务,我想创建这些(对)的列表并并行执行它们。含义:每个Task封装了TaskA和TaskB, TaskB总是等待TaskA先完成。因此,我应该以并行执行TaskA/TaskB

的"set"结束

Task = {TaskA, TaskB}, {TaskA, TaskB}, {TaskA, TaskB}:并行执行这3组任务

    private static async Task TaskA()
    {
        await Task.Delay(2000);
        Console.WriteLine("ended TaskA");
    }
    private static async Task TaskB()
    {
        await Task.Delay(2000);
        Console.WriteLine("ended TaskB");
    }
    static void StartTask()
    {
        Task.Run(() =>
        {
            TaskA().Wait();
            TaskB().Wait();
        });
    }
主:

        List<Task> tasks = new List<Task>();
        int taskCount = 3;
        for (var i = 0; i < taskCount; i++)
        {
            var task = new Task(StartTask);
            tasks.Add(task);
        }
        Parallel.ForEach(tasks, task => task.Start());

当前我得到这个:

ended TaskA
ended TaskA
ended TaskA
ended TaskB
ended TaskB
ended TaskB

我认为输出应该是:

ended TaskA
ended TaskB
ended TaskA
ended TaskB
// etc..

也,尝试了这个,但仍然是相同的问题:

static void StartTask()
{
    Task task = TaskA().ContinueWith(x => TaskB().Wait(), TaskContinuationOptions.OnlyOnRanToCompletion);
}

编辑1:

    Parallel.For(1, taskCount, (i, state) =>
    {
        TaskA().ContinueWith(x => TaskB().Wait(), TaskContinuationOptions.OnlyOnRanToCompletion);
    });

并行执行一对任务

我认为输出应该是:…

不,"平行"不是这个意思。如果您要开始三对,那么我希望您已经看到的输出。

也就是说,代码中有一些东西是没有意义的。首先,要区分"并行"(多个线程)和"并发"(同时做多个事情)。看起来你的任务是自然异步的,所以让我们用异步编程代替线程来重写:

  • await代替Wait
  • 去掉Task.Run

TaskATaskB组成一个新的"配对任务"更容易:

static async Task PairTaskAsync()
{
  await TaskA();
  await TaskB();
}

现在你只需要同时运行这些"配对任务"中的3个。旧的代码使用任务构造函数,然后并行化开始的任务——这是完全错误的,即使我们想要并行化。我们没有;我们想要异步并发。

异步并发通常通过Task.WhenAll:

实现
List<Task> tasks = new List<Task>();
int taskCount = 3;
for (var i = 0; i < taskCount; i++)
  tasks.Add(PairTaskAsync());
await Task.WhenAll(tasks);

或者,为了最简洁:

await Task.WhenAll(Enumerable.Range(0, 3).Select(_ => PairTaskAsync()));