如何确定所有任务何时完成

这是启动多个任务的示例代码

Task.Factory.StartNew(() => { //foreach (KeyValuePair entry in dicList) Parallel.ForEach(dicList, entry => { //create and add the Progress in UI thread var ucProgress = (Progress)fpPanel.Invoke(createProgress, entry); //execute ucProgress.Process(); in non-UI thread in parallel. //the .Process(); must update UI by using *Invoke ucProgress.Process(); System.Threading.Thread.SpinWait(5000000); }); }); .ContinueWith(task => { //to handle exceptions use task.Exception member var progressBar = (ProgressBar)task.AsyncState; if (!task.IsCancelled) { //hide progress bar here and reset pb.Value = 0 } }, TaskScheduler.FromCurrentSynchronizationContext() //update UI from UI thread ); 

当我们使用Task.Factory.StartNew()启动多个任务时,我们可以使用.ContinueWith()块来确定每个任务何时完成。 我的意思是每个任务完成后,ContinueWith会阻止一次。 所以我只想知道TPL库中是否有任何机制。 如果我使用Task.Factory.StartNew()启动10个任务,那么如何在10个任务完成后通知。 请提供示例代码的一些见解。

如果我使用Task.Factory.StartNew()启动10个任务,那么如何在10个任务完成后通知

三种选择:

  • 阻塞Task.WaitAll调用,仅在所有给定任务完成时返回
  • 异步Task.WhenAll调用,返回在完成所有给定任务后完成的任务。 (在.NET 4.5中引入。)
  • TaskFactory.ContinueWhenAll ,它添加一个将在所有给定任务完成后运行的延续任务。

如果我使用Task.Factory.StartNew()启动10个任务,那么如何在10个任务完成后通知

您可以使用Task.WaitAll 。 此调用将阻止当前线程,直到所有任务完成。

旁注:您似乎正在使用TaskParallelThread.SpinWait ,这会使您的代码变得复杂。 我会花一点时间分析这种复杂性是否真的有必要。

您可以使用WaitAll()。 示例:

 Func DummyMethod = () =>{ // When ready, send back complete! return true; }; // Create list of tasks System.Threading.Tasks.Task[] tasks = new System.Threading.Tasks.Task[2]; // First task var firstTask = System.Threading.Tasks.Task.Factory.StartNew(() => DummyMethod(), TaskCreationOptions.LongRunning); tasks[0] = firstTask; // Second task var secondTask = System.Threading.Tasks.Task.Factory.StartNew(() => DummyMethod(), TaskCreationOptions.LongRunning); tasks[1] = secondTask; // Launch all System.Threading.Tasks.Task.WaitAll(tasks); 

另一种方案:

Parallel.For(...)内完成所有操作后,它返回一个ParallelLoopResult , 文档 :

用于在所有线程完成后返回System.Threading.Tasks.ParallelLoopResult对象。 当您手动停止或中断循环迭代时,此返回值很有用,因为ParallelLoopResult存储的信息(例如上次运行完成的迭代)。 如果其中一个线程发生一个或多个exception,则抛出System.AggregateException

ParallelLoopResult类具有IsCompleted属性,当执行Break()方法的Stop()时,该属性设置为false。

例:

 ParallelLoopResult result = Parallel.For(...); if (result.IsCompleted) { //Start another task } 

请注意,它建议仅在手动中断或停止循环时使用它(否则只使用WaitAllWhenAll等)。