Reputation: 357
I have a bunch of tasks defined as:
Task t1 = new Task( () => { /* Do Something */ } );
Task t2 = new Task( () => { /* Do Something */ } );
Task t3 = new Task( () => { /* Do Something */ } );
Task t4 = new Task( () => { /* Do Something */ } );
List<Task> allTasks = new List<Task>();
allTasks.Add(t1);
allTasks.Add(t2); etc.
And then finally:
Task.WhenAll(allTasks).ContinueWith((t) =>
{
MyBlockingCollection.CompleteAdding();
});
foreach (Task t in allTasks)
{
t.Start();
}
My questions regarding the above code:
Is this the correct way to make use of Tasks?
Does Task.WhenAll()
start the tasks by itself or do we have to explicitly start them. If so, do we FIRST start and then do Task.WhenALL()
?
And I need to do exception handling for these tasks as well, Could you please suggest the proper way to handle exceptions within tasks, Ideally I want the task to write out some diagnostics information to a text document if an exception happens.
I'm kind of new to the Tasks world, thanks for your help!
Upvotes: 2
Views: 465
Reputation: 14334
These Task
instances will not run if you simply call the constructor. As the Tasks have not been started, WhenAll
will never return and you will deadlock.
Use System.Threading.Task.Run
instead.
Task t1 = Task.Run(() => { /* Do Something */ });
Task t2 = Task.Run(() => { /* Do Something */ });
...
Remove the loop in which you start the tasks.
Task.Run Method (Action) .NET Framework 4.5
Queues the specified work to run on the ThreadPool and returns a task handle for that work.
Further reading here: Task Parallelism (Task Parallel Library)
Regarding exception handling, you can use the Task
parameter to access all results, even exceptions, from within the continuation:
Task.WhenAll(allTasks).ContinueWith((t) =>
{
if(t.RanToCompletion)
{
MyBlockingCollection.CompleteAdding();
}
else
{
Console.WriteLine(t.Exception);
}
});
More on that here: Exception Handling (Task Parallel Library)
Upvotes: 1
Reputation: 62256
Does Task.WhenAll() start the tasks by itself or do we have to explicitly start them. If so, do we FIRST start and then do Task.WhenAll()?
You need to start every task individually first, after wait for them.
And I need to do exception handling for these tasks as well,..
Every task is independent execution unit, so exception handling happens inside its scope. That means that what you can do is to return an exception from the task as a result. Main thread will read a result and behave appropriately.
Upvotes: 2