In my previous post, I mentioned that I had actually 4 implementations proposal and I commented two of them, which were within the drafted requirements but had an issue with fairness: in both cases, one could bypass the thread pool queue altogether.
Let’s turn our attention to the other two, which are interesting because they share a common issue while having radically different approach.
C#, very short one
|public class Sequencer|
|private readonly object _lock = new object();|
|private Task _task = Task.FromResult(0);|
|public void Dispatch(Action action)|
|_task = _task.ContinueWith(_ => action());|
Clearly, the .Net version benefits from the TPL features. That being said, they are actually very close as they share the same algorithm: ordering is secured by creating a private queue, and non concurrency is ensured by making sure at most one task is enqueued or executing in the .net threadpool.
Contract is fulfilled, albeit with a steep price in terms of performance, or more precisely latency. As a task is actually dispatched only after the previous one have been executed, there is a minimum delay between two tasks. So, once again there is a fairness issue. It is obvious that non sequenced tasks would be executed faster than sequenced ones.