In my program, a lot of Task are started. This Task can start other tasks. But when the program is closed (end of Main method), all running tasks is stopped in middle of their work.
I need when the program is closed, the closing process wait all tasks. For this, I register all started tasks and in last instruction wait all register tasks :
public static class HostedTask
{
private readonly static ConcurrentQueue<Task> _tasks = new ConcurrentQueue<Task>();
public static void Run(Action action)
{
var task = Task.Factory.StartNew(action, TaskCreationOptions.LongRunning);
_tasks.Enqueue(task);
}
public static void Wait()
{
while (_tasks.Any())
{
if (_tasks.TryDequeue(out Task task))
{
task.Wait();
}
}
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
for (int i = 0; i < 100; i+= 10)
{
LongBackgroundWork(i);
}
HostedTask.Wait();
}
static void LongBackgroundWork(int id)
{
HostedTask.Run(() =>
{
Console.WriteLine(id + " Begin");
Thread.Sleep(TimeSpan.FromSeconds(10));
Console.WriteLine(id + " End");
for (var i = id + 1; i < id + 10; i++)
ChildWork(i);
});
}
static void ChildWork(int id)
{
HostedTask.Run(() =>
{
Console.WriteLine(id + " Begin");
Thread.Sleep(TimeSpan.FromSeconds(2));
Console.WriteLine(id + " End");
});
}
This strategy have some problems :
- The collection is never cleaned, it can grow indefinitely
- Need replace all Task declaration
- Don't manage ContinueWith
- Don't manage async/await
Do you have other strategy/idea?
Edit : Complexify the example to work generate child work.