How to determine when all task is completed

2020-06-12 05:26发布

here is sample code for starting multiple task

Task.Factory.StartNew(() =>
        {
            //foreach (KeyValuePair<string, string> 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
  );

when we start multiple task using Task.Factory.StartNew() then we can use .ContinueWith() block to determine when each task finish. i mean ContinueWith block fire once for each task completion. so i just want to know is there any mechanism in TPL library. if i start 10 task using Task.Factory.StartNew() so how do i notify after when 10 task will be finish. please give some insight with sample code.

4条回答
男人必须洒脱
2楼-- · 2020-06-12 05:35

You can use the WaitAll(). Example :

Func<bool> DummyMethod = () =>{
    // When ready, send back complete!
    return true;
};

// Create list of tasks
System.Threading.Tasks.Task<bool>[] tasks = new System.Threading.Tasks.Task<bool>[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);
查看更多
叛逆
3楼-- · 2020-06-12 05:43

if i start 10 task using Task.Factory.StartNew() so how do i notify after when 10 task will be finish

You can use Task.WaitAll. This call will block current thread until all tasks are finished.

Side note: you seem to be using Task, Parallel and Thread.SpinWait, which makes your code complex. I would spend a bit of time analysing if that complexity is really necessary.

查看更多
▲ chillily
4楼-- · 2020-06-12 05:47

if i start 10 task using Task.Factory.StartNew() so how do i notify after when 10 task will be finish

Three options:

  • The blocking Task.WaitAll call, which only returns when all the given tasks have completed
  • The async Task.WhenAll call, which returns a task which completes when all the given tasks have completed. (Introduced in .NET 4.5.)
  • TaskFactory.ContinueWhenAll, which adds a continuation task which will run when all the given tasks have completed.
查看更多
ら.Afraid
5楼-- · 2020-06-12 05:58

Another solution:

After the completion of all the operation inside Parallel.For(...) it return an onject of ParallelLoopResult, Documentation:

For returns a System.Threading.Tasks.ParallelLoopResult object when all threads have completed. This return value is useful when you are stopping or breaking loop iteration manually, because the ParallelLoopResult stores information such as the last iteration that ran to completion. If one or more exceptions occur on one of the threads, a System.AggregateException will be thrown.

The ParallelLoopResult class has a IsCompleted property that is set to false when a Stop() of Break() method has been executed.

Example:

ParallelLoopResult result = Parallel.For(...);

if (result.IsCompleted)
{
    //Start another task
}

Note that it advised to use it only when breaking or stoping the loop manually (otherwise just use WaitAll, WhenAll etc).

查看更多
登录 后发表回答