Task.WaitAll()的行为如何?

sou*_*ura 3 c# c#-5.0

我创建了一个列表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;
}
Run Code Online (Sandbox Code Playgroud)

现在我的问题是.列表中的所有任务是逐个执行还是并行执行.

P =真

所有任务完成后或完成之前设置"p"?

Fab*_*lai 7

对于第一个问题:

这些任务将逐个执行还是异步执行.

(在这里,我想你的意思是同时发生,这并不完全相同)

使用StartNew将在当前运行您的任务TaskScheduler.默认情况下,这意味着它将使用ThreadPool和,如果线程池中有任何可用的插槽,它将并行运行.如果在任务池中获取所有插槽,则可能会限制任务的执行,以避免CPU被淹没,并且可能无法同时执行任务:无法保证.

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

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

从.NET Framework 4.5开始,您可以使用Task.Run(Action)方法作为使用默认参数调用StartNew(Action)的快速方法.但请注意,两种方法之间的行为存在差异:默认情况下,Task.Run(Action)不允许使用TaskCreationOptions.AttachedToParent选项启动的子任务附加到当前Task实例,而StartNew(Action)确实.

对于第二个问题

所有任务完成后或完成之前设置"p"?

简短的回答是肯定的.

但是,您应该考虑使用另一种方法,因为这将阻止您的线程并等待空闲.另一种方法是,如果可以,则将控制权交还给调用者,因此线程被释放并可供CPU使用.如果运行此代码的线程是a的一部分,则尤其如此ThreadPool.

因此,你应该更喜欢使用WhenAll().它返回一个可以等待或ContinueWith可以调用的任务

例:

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