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"是在所有任务完成时设置的还是在任务完成之前设置的?
第一个问题:
这些任务是一个一个执行还是异步执行。
(在这里,我想你指的是并发的,这并不完全相同)
使用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方法将阻塞调用方法的执行,直到传递给它的所有任务都完成执行。
所以布尔变量是在所有任务完成后设置的