任务执行取决于等待机制?

问题描述 投票:0回答:1

这是我正在运行的伪代码:

变体#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之间出现根本不同?这是设计,我只是不明白这是如何工作的?

我的(显然失败的)理解/推测是,在两种情况下,doWork将以多线程/异步方式调用,并行(如果可用),唯一的区别是调用代码将以不同方式等待完成。但是如何实际执行任务将是相同的,因为它们以相同的方式安排/“运行”。

但是从调试两个版本的代码后我可以看出,变量#1导致doWork以真正的并行/全多线程方式调用,而变体#2似乎表现得像是单线程,顺序执行每项任务。

我错过了什么?

c# multithreading plinq
1个回答
3
投票

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

AsParallel()Task.Run()混合起来是很危险的事情,除非你确定你在做什么:没有努力它可能会显着降低你的表现,而不是像你期望的那样使它变得更好。

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

© www.soinside.com 2019 - 2024. All rights reserved.