AsyncEventHandlers 1.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package AsyncEventHandlers --version 1.0.1                
NuGet\Install-Package AsyncEventHandlers -Version 1.0.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AsyncEventHandlers" Version="1.0.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add AsyncEventHandlers --version 1.0.1                
#r "nuget: AsyncEventHandlers, 1.0.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install AsyncEventHandlers as a Cake Addin
#addin nuget:?package=AsyncEventHandlers&version=1.0.1

// Install AsyncEventHandlers as a Cake Tool
#tool nuget:?package=AsyncEventHandlers&version=1.0.1                

AsyncEventHandlers

This library provides true thread-safe asynchronus event handlers for .NET.\

Setup

Just install the latest release from NuGet. Alternatively you can download it from the Releases tab aswell.

Usage

Note that when registering/unregistering a lot from different threads, should consider using AsyncEventHandler instead of AsyncEventHandlerDelegate as the latter uses the built-in non thread-safe registering/unregistering mechanism.

Using the delegate

The AsyncEventHandlerDelegate delegate is basically being used like the built-in EventHandler type apart from the invocation. See below.

Declaring an event:

public event AsyncEventHandlerDelegate? MyEvent;

// Or with custom event args:
public class MyAsyncEventArgs : AsyncEventArgs
{
    public string? Message { get; set; }
}

public event AsyncEventHandlerDelegate<MyAsyncEventArgs>? MyCustomEvent;

Invoking the event:

try
{
    await MyEvent.InvokeAsync(this, new AsyncEventArgs());
    // or with a cancellation token
    var cts = new CancellationTokenSource();
    await MyEvent.InvokeAsync(this, new AsyncEventArgs(), cts.Token);
}
catch (OperationCanceledException)
{
    // Cancellation token was cancelled
}
catch (ObjectDisposedException)
{
    // Cancellation token was disposed
}
catch (Exception)
{
    // Some registered event(s) have thrown an exception
}

Registering/Unregistering to the event:

class WebsocketServer
{
    public event AsyncEventHandlerDelegate? MyEvent;
}

var ws = new WebsocketServer();
ws.MyEvent += Ws_MyEvent;   // Register
ws.MyEvent -= Ws_MyEvent;   // Unregister

static Task Ws_MyEvent(object? sender, AsyncEventArgs e)
{
    if (e.CancellationToken.IsCancellationRequested)
    {
        Console.WriteLine("The cancellation token was cancelled!");
    }

    return Task.CompletedTask;
}

Using the AsyncEventHandler class

The AsyncEventHandler type is completely thread-safe, no matter how many events are registered/unregistered from different threads. It can almost be used as the delegate described before apart from the declaration.

Declaring an event:

public AsyncEventHandler MyEvent = new AsyncEventHandler();

// Or with custom event args:
public class MyAsyncEventArgs : AsyncEventArgs
{
    public string? Message { get; set; }
}

public AsyncEventHandlerDelegate<MyAsyncEventArgs> MyCustomEvent = new AsyncEventHandler<MyAsyncEventArgs>();

Registering/Unregistering to the event:

class WebsocketServer
{
    public AsyncEventHandler MyEvent = new AsyncEventHandler();
}

var ws = new WebsocketServer();
ws.MyEvent += Ws_MyEvent;   // Register
ws.MyEvent -= Ws_MyEvent;   // Unregister
// Or use the methods
ws.MyEvent.Register(Ws_MyEvent);
ws.MyEvent.Unregister(Ws_MyEvent);

static Task Ws_MyEvent(object? sender, AsyncEventArgs e)
{
    if (e.CancellationToken.IsCancellationRequested)
    {
        Console.WriteLine("The cancellation token was cancelled!");
    }

    return Task.CompletedTask;
}

Sample projects

More samples can be found in the Samples directory.

License

AsyncEventHandlers is licensed under The Unlicense, see LICENSE.txt for more information.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on AsyncEventHandlers:

Package Downloads
ZCStudio.CoreLib.IO.Ports

CoreLib

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.0.1 5,335 12/3/2022
2.0.0 566 5/3/2022
1.0.1 468 3/22/2022
1.0.0 437 3/22/2022