Giter Club home page Giter Club logo

serialqueue's Introduction

SerialQueue

Lightweight, high-performance C# implementations of FIFO serial queues from Apple's GCD, which are often much better to use for synchronization rather than locks - they don't block caller's thread, and rather than creating new threads - they use thread pool.

Task-based implementation is more simple and convenient, while non-task is faster (check benchmark results).

Covered with tests.

Table of contents

Benchmark results

Chart 1: Approximate synchronization costs depending on the operation duration (smaller is better).

chart-1

Chart 2: Zoomed in (smaller is better).

chart-2

Chart 3: Zoomed in for the shortest operations (smaller is better).

chart-3

  • The X axis is the time of the operation to be synchronized, in milliseconds.
  • The Y axis shows approximate synchronization costs in processor ticks.

Synchronization mechanisms:

  • SpinLock, Monitor, Mutex - standard synchronization primitives.
  • SemaphoreSlim is a simplified alternative to Semaphore.
  • TPL Dataflow ActionBlock - implementation of a queue using TPL Dataflow ActionBlock.
  • SerialQueue (by @borland) - queue implementation from user @borland.
  • SerialQueue is a lightweight serial queue implementation from this repository.
  • SerialQueue Tasks is a Task-based serial queue implementation from this repository.

Interface

// Task based version (recommended)
// SerialQueue/SerialQueueTasks.cs
class SerialQueue {
    Task Enqueue(Action action);
    Task<T> Enqueue<T>(Func<T> function);
    Task Enqueue(Func<Task> asyncAction);
    Task<T> Enqueue<T>(Func<Task<T>> asyncFunction);
}

// Lightweight version
// SerialQueue/SerialQueue.cs
class SerialQueue {
  void DispatchSync(Action action);
  void DispatchAsync(Action action);
}

Installation

Just copy the source code of SerialQueue/SerialQueueTasks.cs or SerialQueue/SerialQueue.cs file to your project.

Task-based example

readonly SerialQueue queue = new SerialQueue();

async Task SomeAsyncMethod()
{
    // C# 5+
    
    await queue.Enqueue(SyncAction);
    
    var result = await queue.Enqueue(AsyncFunction);
    
    // Old approach
    
    queue.Enqueue(AsyncFunction).ContinueWith(t => {
        var result = t.Result;
    });
}

Troubleshooting

Deadlocks

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

var queue = new SerialQueue();

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:

// Bad

async Task Run()
{
  await FunctionA();
  await FunctionB();
  await FunctionC(); // deadlock
}

async Task FunctionA() => await queue.Enqueue(async () => { ... });

async Task FunctionB() => await queue.Enqueue(async () => { ... });

async Task FunctionC() => await queue.Enqueue(async () =>
  await FunctionA();
  ...
  await FunctionB();
});

// Good

async Task Run()
{
    await queue.Enqueue(FunctionA);
    await queue.Enqueue(FunctionB);
    await queue.Enqueue(FunctionC);
}

async Task FunctionA() { ... };

async Task FunctionB() { ... };

async Task FunctionC()
{
  await FunctionA();
  ...
  await FunctionB();
};

serialqueue's People

Contributors

gentlee avatar hackmodford avatar rihadavid avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.