并行执行一对任务
本文关键字:任务 并行执行 | 更新日期: 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
将TaskA
和TaskB
组成一个新的"配对任务"更容易:
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()));