jpmikkers / Baksteen.Async.TaskQueue

Lightweight C# implementation of FIFO serial queue from ObjC.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Baksteen.Async.TaskQueue

TaskQueue is a lightweight C# async implementation of a FIFO execution queue. It enables async queueing of async work that will be executed in guaranteed first-in first-out (FIFO) order. It is a fork of Gentlee's SerialQueue, but in this case the implementation is fully async based and maybe a bit easier to understand.

Interface

using Baksteen.Async;

class TaskQueue {
    Task Enqueue(Action action);
    Task<T> Enqueue<T>(Func<T> function);
    Task Enqueue(Func<Task> asyncAction);
    Task<T> Enqueue<T>(Func<Task<T>> asyncFunction);
}

Example

readonly TaskQueue queue = new TaskQueue();

async Task SomeAsyncMethod()
{
    await queue.Enqueue(AsyncAction);
    
    var result = await queue.Enqueue(AsyncFunction);
}

Troubleshooting

Deadlocks

Nesting and awaiting queue.Enqueue leads to deadlock in the queue:

var queue = new TaskQueue();

await queue.Enqueue(async () =>
{
  await queue.Enqueue(async () =>
  {
    // This code will never run because it waits until the first task executes,
    // and first task awaits while this one finishes.
    // Queue is locked.
  });
});

This particular case can be fixed by either not awaiting nested Enqueue or not putting nested task to queue at all, because it is already in the queue. Overall it is better to implement code not synced first, but later sync it in the upper layer that uses that code, or in a synced wrapper.

About

Lightweight C# implementation of FIFO serial queue from ObjC.

License:MIT License


Languages

Language:C# 100.0%