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