How to determine when all task is completed

19,592

Solution 1

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.

Solution 2

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.

Solution 3

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);

Solution 4

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).

Share:
19,592
Thomas
Author by

Thomas

i am developer. i am working with .Net technology (v1.1 &amp; v2.0) last 4 year. i like this forum for fast &amp; good response and that is why i joined this forum. my friends profile id Mou :- http://stackoverflow.com/users/728750/user728750?tab=questions and Keith :- http://stackoverflow.com/users/750398/keith-costa thanks

Updated on June 05, 2022

Comments

  • Thomas
    Thomas almost 2 years

    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.

  • Mez
    Mez almost 11 years
    The "<" and the ">" did not appear. Trying here : Func<bool> DummyMethod = () =>{ // When ready, send back complete! return true; };
  • Kirill Shlenskiy
    Kirill Shlenskiy almost 11 years
    TaskFactory.ContinueWhenAll(...) is handy too if you're restricted to 4.0.
  • Jon Skeet
    Jon Skeet almost 11 years
    @KirillShlenskiy: Ooh, nice - missed that, will add it.
  • svick
    svick almost 11 years
    I think the “Launch all” comment is quite confusing, since WaitAll() doesn't actually launch anything.
  • Thomas
    Thomas almost 11 years
    i am working in net version 4.0. i want to start 10 task and i want to be notify when each task will be completed and also one last notification should come when 10 task will be completed. please give me idea. thanks
  • Thomas
    Thomas almost 11 years
    i am working in net version 4.0. i want to start 10 task and i want to be notify when each task will be completed and also one last notification should come when 10 task will be completed. please give me idea. thanks
  • oleksii
    oleksii almost 11 years
    @Thomas I would add a .ContinueWith to each task to send notification on job completion and a final line would be Task.WaitAll(). In other words, each task provides notification when finished by using tasks chaining, where the chained task simply reports on completion. There will also be a call to the Task.WaitAll method - this will allow you to make a notification about all tasks work completion. Make sense?
  • Thomas
    Thomas almost 11 years
    i am working in net version 4.0. i want to start 10 task and i want to be notify when each task will be completed and also one last notification should come when 10 task will be completed. please give me idea. thanks
  • Jon Skeet
    Jon Skeet almost 11 years
    @Thomas: It sounds like you want ContinueWith on each task, then a call to ContinueWhenAll as well with the "everything is completed" notification.
  • Thomas
    Thomas almost 11 years
    thanks. can u give me some hint or dummy sample code for using ContinueWhenAll() & ContinueWith() togather.
  • Jon Skeet
    Jon Skeet almost 11 years
    @Thomas: Well what have you tried, and what went wrong? You're already calling ContinueWith. You just need to collect the tasks you're starting, and then call ContinueWhenAll - what are you finding difficult about it?
  • Thomas
    Thomas almost 11 years
    i found ContinueWhenAll is not showing in dotnet v4.0. is there any other option available?
  • Jon Skeet
    Jon Skeet almost 11 years
    @Thomas: It's an instance method on TaskFactory. You should be able to use it in .NET 4.
  • SaddamBinSyed
    SaddamBinSyed about 6 years
    @JonSkeet, If i use await inside the task then HOw will know that this task is completed or not?
  • Jon Skeet
    Jon Skeet about 6 years
    @SaddamBinSyed: I'm afraid I really don't follow what this comment has to do with this 5-year-old answer.
  • SaddamBinSyed
    SaddamBinSyed about 6 years
    @JonSkeet, I got what i searched you can look at this link my exact question stackoverflow.com/questions/49650283/…
  • Jon Skeet
    Jon Skeet about 6 years
    @SaddamBinSyed: The comments there gave you the answer though: use Task.Run instead. It's still unclear to me what this question has to do with that one, really. (You were already discovering that the task returned by StartNew had completed - it's just that wasn't doing what you expected it to because you were passing in an async lambda expression that started a task, but didn't return it.)