AsyncEx - A Helper Library for async/await

AsyncEx - A Helper Library for async/await

A helper library for async/await

Last updated 7/8/2022 7:21 AM
黑哥聊dotNet
4 min read
Category
.NET
Tags
.NET C#

Introduction

A helper library for async/await.

Supports netstandard1.3 (including .NET 4.6, .NET Core 1.0, Xamarin.iOS 10, Xamarin.Android 7, Mono 4.6, and Universal Windows 10).

Installation

Install NuGet package Nito.AsyncEx

Install-Package Nito.AsyncEx -Version 5.1.2

Usage

AsyncLock

The AsyncLock constructor can take an asynchronous wait queue; pass a custom wait queue to specify your own queuing logic.

private readonly AsyncLock _mutex = new AsyncLock();
public async Task UseLockAsync()
{
  // AsyncLock can be locked asynchronously
  using (await _mutex.LockAsync())
  {
    // It's safe to await while the lock is held
    await Task.Delay(TimeSpan.FromSeconds(1));
  }
}

AsyncLock also fully supports cancellation.

public async Task UseLockAsync()
{
  // Attempt to take the lock only for 2 seconds.
  var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2));

  // If the lock isn't available after 2 seconds, this will
  //  raise OperationCanceledException.
  using (await _mutex.LockAsync(cts.Token))
  {
    await Task.Delay(TimeSpan.FromSeconds(1));
  }
}

AsyncLock also has a synchronous API. This allows some threads to acquire the lock asynchronously while other threads acquire it synchronously (blocking the thread).

public async Task UseLockAsync()
{
  using (await _mutex.LockAsync())
  {
    await Task.Delay(TimeSpan.FromSeconds(1));
  }
}

public void UseLock()
{
  using (_mutex.Lock())
  {
    Thread.Sleep(TimeSpan.FromSeconds(1));
  }
}

AsyncContext

The AsyncContext type provides a context for executing asynchronous operations. The await keyword requires a context to return to. For most client programs, this is a UI context; for most server programs, this is a thread pool context. AsyncContextThread is a separate thread or task that runs an AsyncContext. AsyncContextThread is not derived from the Thread class. The AsyncContext thread starts running immediately after creation. AsyncContextThread will stay in its loop until another thread calls JoinAsync. Disposing an AsyncContextThread also asks it to exit.

class Program
{
  static async Task<int> AsyncMain()
  {
    ..
  }

  static int Main(string[] args)
  {
    return AsyncContext.Run(AsyncMain);
  }
}

AsyncMonitor

In a monitor, a task may decide to wait for a signal by calling WaitAsync. While waiting, it temporarily leaves the monitor until it receives a signal and re-enters the monitor. The task returned by EnterAsync will enter the Completed state after entering the monitor. If a signal is sent before the wait is satisfied, the same task will enter the Canceled state; in that case, the task will not enter the monitor due to the CancellationToken.

The task returned by WaitAsync will enter the Completed state after receiving a signal and re-entering the monitor. If a signal is sent before the wait is satisfied, the same task will enter the Canceled state; in that case, the task will wait to enter the Canceled state until it re-enters the monitor. Keep in mind that from the time WaitAsync is called to the completion of its returned task, the calling task has left the monitor.

Finally, if you like my articles, please follow and give a thumbs up. Hope the .NET ecosystem gets better and better!

Keep Exploring

Related Reading

More Articles