How Task.WaitAll() Behave?

本文关键字:Behave Task WaitAll How | 更新日期: 2023-09-27 18:15:43

我已经创建了一个Task列表,如下所示:

public void A()
{
}
public void B()
{
}
public void C()
{
}
public void Ex()
{
   Task.WaitAll(Task.Factory.StartNew(A), Task.Factory.StartNew(B), Task.Factory.StartNew(C));
   var p=true;
}
现在我的问题是。列表中的所有任务是一个接一个执行还是并行执行?

p = true

"p"是在所有任务完成时设置的还是在任务完成之前设置的?

How Task.WaitAll() Behave?

第一个问题:

这些任务是一个一个执行还是异步执行。

(在这里,我想你指的是并发的,这并不完全相同)

使用StartNew将在当前TaskScheduler中运行任务。默认情况下,这意味着它将使用ThreadPool,如果线程池中有任何可用的插槽,它将并行运行。如果任务池中所有的槽位都被占用,可能会限制任务的执行,以避免CPU超载,并且任务可能不会同时执行:没有保证。

这是一个简化的解释,关于调度策略的更完整和详细的解释在TaskScheduler文档中有解释。

作为旁注。StartTask的文档提到了StartNew(Action)Run(Action)之间的细微差别。与其他答案不同,它们并不完全相等。

从。net Framework 4.5开始,您可以使用Task.Run(Action)方法作为使用默认参数调用StartNew(Action)的快速方法。注意,这两个方法在以下方面的行为是不同的:Task.Run(Action)默认情况下不允许使用TaskCreationOptions启动子任务。attachedtopparent选项附加到当前Task实例,而StartNew(Action)则执行。

第二题

"p"是在所有任务完成时设置的还是在任务完成之前设置的?

简短的回答是肯定的。

但是,您应该考虑使用另一种方法,因为这种方法会阻塞您的线程并无所事事地等待。另一种方法是,如果可以的话,将控制权交还给调用者,这样线程就会被释放,可以由CPU使用。如果运行此代码的线程是ThreadPool的一部分,则尤其如此。 因此,您应该更喜欢使用WhenAll()。它返回一个任务,该任务可以等待,也可以调用ContinueWith

的例子:

var tasks = new Task[] {Task.Factory.StartNew(A), Task.Factory.StartNew(B), Task.Factory.StartNew(C)}; 
await Task.WhenAll(tasks);

first:您以错误的方式创建任务。当你实例化一个任务时,你需要对它调用Start方法,否则它什么也做不了。

new Task(() => /* Something * /).Start();

如果你用刚才的方式创建任务(通过调用构造函数并点击start或使用taskfactory甚至task . run),默认情况下一个ThreadPool线程将专用于任务,因此任务是并行执行的。

任务。WhenAll方法将阻塞调用方法的执行,直到传递给它的所有任务都完成执行。

所以布尔变量是在所有任务完成后设置的