I've created a Producer/Consumer program which uses N threads of invocations ( currently only 1).
void Main()
{
var pcQ = new PCQueue(1); // Maximum concurrency of 1
foreach (int item in Enumerable.Range(1, 5))
{
pcQ.Enqueue(async () =>
{
await Task.Delay(1000); //<-------simulation of work
Console.WriteLine(item);
});
}
}
public class PCQueue
{
private BlockingCollection<Task> _taskQ = new BlockingCollection<Task>();
public Task Enqueue(Action action, CancellationToken cancelToken = default(CancellationToken))
{
var task = new Task(action, cancelToken);
_taskQ.Add(task);
return task;
}
public PCQueue(int workerCount)
{
for (int i = 0; i < workerCount; i++)
Task.Run(Consume);
}
async Task Consume()
{
foreach (var task in _taskQ.GetConsumingEnumerable())
try
{
task.RunSynchronously();
}
catch (InvalidOperationException)
{
}
}
}
The output is :
The problem is that after a second, I see all results at once.
A new item is being fetched from the blocking collection before the previous item has completed.
This is happening because of this line (without awaiting):
task.RunSynchronously();
Question:
How can I await
this task to complete before another one is fetched.
I'm expecting to see a new line after every second.