I'm trying to build up a kind of scheduler (this might not be the relevant term) that would run in sequence a number of tasks.
Here is my POC code (please ignore the queue/dequeue mechanism which is poor, but not the problem here I guess)
EDIT: thanks to the help of @Theraot
static void Main(string[] args)
{
ProcessingQueue o_q = new ProcessingQueue();
o_q.Enqueue(async () => { await SimulateTaskSequence(1); });
o_q.Enqueue(async () => { await SimulateTaskSequence(2); });
Console.ReadLine();
}
public static async Task SimulateTaskSequence(int taskNbr)
{
Console.WriteLine("T{0} - Working 1sec", taskNbr);
Thread.Sleep(1000);
Console.WriteLine("T{0} - Zzz 1st 1sec", taskNbr);
await Task.Delay(1000);
Console.WriteLine("T{0} - Working 1sec", taskNbr);
Thread.Sleep(1000);
Console.WriteLine("T{0} - Done", taskNbr);
}
public class ProcessingQueue
{
Queue<Action> _Queue = new Queue<Action>();
private bool _stillRunning = false;
public void Enqueue(Action a)
{
lock (_Queue)
{
_Queue.Enqueue(a);
if (_stillRunning == false)
{
StartProcessing();
}
}
}
private void StartProcessing()
{
_stillRunning = true;
Task.Run(async () =>
{
Action a = null;
while (true)
{
lock (_Queue)
{
if (_Queue.Any() == true)
{
a = _Queue.Dequeue();
}
else
{
break;
}
}
await Task.Run(a); //how to wait for all subtasks!!???
}
_stillRunning = false;
});
}
My problem is that as soon as the first await of the 1st task (T1) occurs, the second tasks (T2) starts to get executed.
I get the following output:
T1 - Working 1sec
T1 - Zzz 1st 1sec
T2 - Working 1sec
T2 - Zzz 1st 1sec
T1 - Working 1sec
T1 - Done
T2 - Working 1sec
T2 - Done
But what I'm expecting would be:
T1 - Working 1sec
T1 - Zzz 1st 1sec
T1 - Working 1sec
T1 - Done
T2 - Working 1sec
T2 - Zzz 1st 1sec
T2 - Working 1sec
T2 - Done
I understand why this is the default behavior, but I need to change that. I was playing around TaskContinuationOptions and TaskCreationOptions in a new TaskFactory, but without better results. Is that even possible?
Thanks a lot Christophe