我创建了一个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 =真
“p”是在所有任务完成之后还是在完成之前设置的?
答案 0 :(得分:7)
对于第一个问题:
这些任务是逐个执行还是异步执行。
(在这里,我想你的意思是同时,这不完全一样)
使用StartNew
将在当前TaskScheduler
中运行您的任务。默认情况下,这意味着它将使用ThreadPool
,如果线程池中有任何可用的插槽,它将并行运行。如果在任务池中获取所有插槽,则可能会限制任务的执行,以避免CPU被淹没,并且可能无法同时执行任务:无法保证。
这是一个简化的解释,对调度策略的更完整和详细的解释是explained on the TaskScheduler documentation。
作为旁注。 documentation for StartTask提到了StartNew(Action)
和Run(Action)
之间的细微差别。与其他答案不同,它们并不完全等效。
从.NET Framework 4.5开始,您可以使用Task.Run(Action)方法作为使用默认参数调用StartNew(Action)的快速方法。但请注意,两种方法之间的行为存在差异:默认情况下,Task.Run(Action)不允许使用TaskCreationOptions.AttachedToParent选项启动的子任务连接到当前Task实例,而StartNew(Action)确实。
对于第二个问题
" P"在所有任务完成之后或完成之前设置?
简短的回答是肯定的。
但是,你应该考虑使用另一种方法,因为这会阻塞你的线程并等待空闲。另一种方法是,如果可以,则将控制权交还给调用者,因此线程被释放并可供CPU使用。如果运行此代码的线程是ThreadPool
。
因此,您应该更喜欢using WhenAll()
。它返回一个可以等待的任务,或者可以调用ContinueWith
的任务
示例:
var tasks = new Task[] {Task.Factory.StartNew(A), Task.Factory.StartNew(B), Task.Factory.StartNew(C)};
await Task.WhenAll(tasks);
答案 1 :(得分:2)
第一: 你正在以错误的方式创建任务。当你实例化一个任务时,你需要在它上面调用Start方法,否则它什么都没有。
new Task(() => /* Something * /).Start();
如果您按照刚才的方式创建任务(通过调用构造函数并按下启动或使用TaskFacotry甚至Task.Run),默认情况下ThreadPool线程将专用于该任务,因此任务将并行执行。 / p>
Task.WhenAll方法将阻止调用方法的执行,直到传递给它的所有任务都完成为止。
所以在完成所有任务后设置布尔变量。