Parallel.Invoke和多次调用Task.Run是否相同?

3

Task.Run: 将指定的任务排队到ThreadPool上运行,并返回该任务或Task<TResult>句柄。

Parallel.Invoke: 执行每个提供的操作,可能并行执行。

它们有效地从线程池中启动一个新线程。那么,Parallel.Invoke是否相当于调用多个Task.Run


1
这个回答解决了你的问题吗?Task.Factory.StartNew vs. Parallel.Invoke - JHBonarius
@JHBonarius 我认为,尽管相关问题在主题上非常相似,但它并不是一个完全的重复,因为Task.Factory.StartNewTask.Run并不完全相同。如今,Task.Factory.StartNew被认为是一种非常专业的工具,所以我认为有兴趣了解Parallel.InvokeTask.Run之间的区别的人不应该先学习Task.Factory.StartNewTask.Run之间的区别。 - Theodor Zoulias
@TheodorZoulias 当然,但这是2013年的问题。而且我认为(我认为这甚至是指南),您应该尽可能标记重复内容,以防止信息分散。如果需要,应在那里放置更新后的答案。 - JHBonarius
@JHBonarius 重复问题 的定义是:“已经在本网站上得到回答的问题。所有关闭操作都应该进行苹果对苹果的比较。换句话说,如果问题与先前提出的问题完全匹配,或者问题密切相关并且有一个答案可以解决两个问题,则应该进行关闭。”我认为我不能在其他问题中发布我的答案,因为那里不是合适的主题。 - Theodor Zoulias
1个回答

3

所以你想比较这两种技术:

Parallel.Invoke(source.Select(source => () => ProcessItem(source)).ToArray());

Task.WaitAll(source.Select(source => Task.Run(() => ProcessItem(source))).ToArray());

有一点相似和两点不同之处。相似之处在于,无论某些操作是否失败,在Parallel.Invoke/Task.WaitAll返回之前,所有操作都将被调用并完成。没有支持快速失败的策略。

这两个区别是:

  1. Parallel.Invoke使用当前线程作为其中一个工作线程。相反,Task.WaitAll+Task.Run专门使用ThreadPool线程。当工作线程在工作时,当前线程会被阻塞而无法进行任何操作。

  2. Parallel.Invoke可以配置特定的MaxDegreeOfParallelismTaskSchedulerCancellationTokenParallelOptions)。Task.Run不支持此功能。虽然Task.Factory.StartNew也支持,但相对来说比较笨重。


你应该提到 await Task.WhenAll 选项,在那里你也解除当前线程的阻塞状态。 - JHBonarius
Parallel.Invoke使用当前线程作为工作线程之一。- 还会使用线程池中的其他线程吧? - variable
@variable 是的,确切地说。默认情况下,其他线程来自于“线程池”。 - Theodor Zoulias
在这种情况下,我还应该提到Parallel.Invoke可以通过await Task.Run(() => Parallel.Invoke(/*...*/))转移到ThreadPool。我更喜欢保持简单,因为OP在问题正文或标签中没有提及异步。 - Theodor Zoulias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接