任务执行依赖于等待机制?

Task execution dependent upon the waiting mechanism?

这是我的伪代码 运行:

变体 #1:

List<Task> tasks = new List<Task>();
foreach (...)
{
    Task task = Task.Run(() =>
    {
        doWork();
    });
    tasks.Add(task);
}

Task.WhenAll(tasks.AsParallel()).ContinueWith((t) =>
{
    // process results/handle errors
    ...
});

变体#2:

List<Task> tasks = new List<Task>();
foreach (...)
{
    Task task = Task.Run(() =>
    {
        doWork();
    });
    tasks.Add(task);
}

Task.WhenAll(tasks.AsParallel()).Wait();

// process results/handle errors
...

我的问题是,为什么doWork的调用方式在#1和#2之间显得根本不同?这是设计使然,我只是不明白它应该如何工作?

我的(显然失败了)understanding/presumption 是 doWork 将以 multi-threaded/async 方式调用,如果可用,则在 both[=33] 中并行调用=] 场景,唯一的区别是 调用代码 等待完成的方式不同。但是任务实际执行的方式是相同的,因为它们的计划/"run"方式相同。

但是根据我在调试两个版本的代码后所知道的,变体 #1 导致 doWork 以真正的 parallel/fully-multithreaded 方式被调用,而变体 #2 似乎表现得像它是每个任务的单线程顺序执行。

我错过了什么?

.AsParallel()LINQ多线程扩展,与Task无关。 Task.Run(...) 本身就足以满足大多数情况,可以使用或不使用 LINQ

混合使用 AsParallel()Task.Run() 是危险的事情,除非您确定自己在做什么:如果不加努力,它可能会显着降低您的性能,而不是像您期望的那样提高性能。

最后,不要Wait() Task:它将以常规同步方式强制执行,从而取消所有Task的好处。