I use Task Parallel Library to start some tasks, like so:
public static void Main()
{
for (var i = 0; i < 10; i++)
{
var x = i;
Task.Factory.StartNew(() => new WorkerClass(x).Do());
}
// (*) Here I'd like to wait for all tasks to finish
Task.WaitAll();
Console.WriteLine("Ready.");
Console.ReadLine();
}
The problem is that some tasks can create new tasks themselves. This is how WorkerClass
looks like:
public class WorkerClass
{
private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();
private readonly int _i;
public WorkerClass(int i)
{
_i = i;
}
public void Do()
{
if (_i % 3 == 0)
Task.Factory.StartNew(() => new WorkerClass(_i + 101).Do());
Log.Info("Started {0}", _i);
Thread.Sleep(2000);
Log.Info("Done {0}", _i);
}
}
For every value of i
that's a multiple of 3, a new Task is started.
I'd like to be able to wait until all tasks (including the ones created by other tasks) are finished.
Is there a clean/built-in way to do this (with or without TPL)?
You don't have to do anything special, Parallel. Foreach() will wait until all its branched tasks are complete. From the calling thread you can treat it as a single synchronous statement and for instance wrap it inside a try/catch.
WhenAll() method in . NET Core. This will upload the first file, then the next file. There is no parallelism here, as the “async Task” does not automatically make something run in in parallel.
It is always advised to use tasks instead of thread as it is created on the thread pool which has already system created threads to improve the performance. The task can return a result. There is no direct mechanism to return the result from a thread. Task supports cancellation through the use of cancellation tokens.
Keep a reference to all top-level tasks and then just use WaitAll
:
var tasks = new Task[10];
for (var i = 0; i < 10; i++)
{
var x = i;
tasks[i] = Task.Factory.StartNew(() => new WorkerClass(x).Do());
}
Task.WaitAll( tasks );
As for the child tasks, just make sure you attach them to the parent task. This means that the parent task will not go into a complete state until all child tasks are also finished.
Task.Factory.StartNew(() => { }, TaskCreationOptions.AttachedToParent);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With