任务执行依赖于等待机制?
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
的好处。
这是我的伪代码 运行:
变体 #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
的好处。