如何确定所有任务何时完成
这是启动多个任务的示例代码
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 。 此调用将阻止当前线程,直到所有任务完成。
旁注:您似乎正在使用Task
, Parallel
和Thread.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 }
请注意,它建议仅在手动中断或停止循环时使用它(否则只使用WaitAll
, WhenAll
等)。