Task.Run
: 将指定的任务排队到ThreadPool
上运行,并返回该任务或Task<TResult>
句柄。
Parallel.Invoke
: 执行每个提供的操作,可能并行执行。
它们有效地从线程池中启动一个新线程。那么,Parallel.Invoke
是否相当于调用多个Task.Run
?
Task.Run
: 将指定的任务排队到ThreadPool
上运行,并返回该任务或Task<TResult>
句柄。
Parallel.Invoke
: 执行每个提供的操作,可能并行执行。
它们有效地从线程池中启动一个新线程。那么,Parallel.Invoke
是否相当于调用多个Task.Run
?
所以你想比较这两种技术:
Parallel.Invoke(source.Select(source => () => ProcessItem(source)).ToArray());
Task.WaitAll(source.Select(source => Task.Run(() => ProcessItem(source))).ToArray());
有一点相似和两点不同之处。相似之处在于,无论某些操作是否失败,在Parallel.Invoke
/Task.WaitAll
返回之前,所有操作都将被调用并完成。没有支持快速失败的策略。
这两个区别是:
Parallel.Invoke
使用当前线程作为其中一个工作线程。相反,Task.WaitAll
+Task.Run
专门使用ThreadPool
线程。当工作线程在工作时,当前线程会被阻塞而无法进行任何操作。
Parallel.Invoke
可以配置特定的MaxDegreeOfParallelism
、TaskScheduler
和CancellationToken
(ParallelOptions
)。Task.Run
不支持此功能。虽然Task.Factory.StartNew
也支持,但相对来说比较笨重。
await Task.WhenAll
选项,在那里你也解除当前线程的阻塞状态。 - JHBonariusParallel.Invoke
可以通过await Task.Run(() => Parallel.Invoke(/*...*/))
转移到ThreadPool
。我更喜欢保持简单,因为OP在问题正文或标签中没有提及异步。 - Theodor Zoulias
Task.Factory.StartNew
与Task.Run
并不完全相同。如今,Task.Factory.StartNew
被认为是一种非常专业的工具,所以我认为有兴趣了解Parallel.Invoke
和Task.Run
之间的区别的人不应该先学习Task.Factory.StartNew
和Task.Run
之间的区别。 - Theodor Zoulias