Skip to content

Commit

Permalink
Refactored the library and upgraded to .NET Standard 2.1
Browse files Browse the repository at this point in the history
* Removed the requirement to inherit your event classes from AsyncEventArgs
* Structs can now be used for event args
* Added AsyncEventHandlers without event args
* Updated samples
  • Loading branch information
TheDusty01 committed Dec 3, 2022
1 parent bff66c9 commit 95c2874
Show file tree
Hide file tree
Showing 15 changed files with 545 additions and 358 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
56 changes: 39 additions & 17 deletions AsyncEventHandlers.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,49 @@ public static void Main()
BenchmarkRunner.Run<Program>();
}

private static AsyncEventHandler<AsyncEventArgs> Struct_AsyncEventHandler = new AsyncEventHandler<AsyncEventArgs>();
private static event AsyncEventHandlerDelegate<AsyncEventArgs> Delegate_AsyncEventHandler;
private static AsyncEventHandler Struct_AsyncEventHandler = new AsyncEventHandler();
private static WeakAsyncEventHandler WeakAsyncEventHandler = new WeakAsyncEventHandler();
private static event AsyncEventHandlerDelegate<IAsyncEventArgs> Delegate_AsyncEventHandler;

private readonly List<object> eventSources = new List<object>();

public Program()
{
for (int i = 0; i < 100; i++)
{
eventSources.Add(new object());


Struct_AsyncEventHandler += Struct_AsyncEventHandler_Event;
WeakAsyncEventHandler.Register(eventSources[i], WeakAsyncEventHandler_Event);
Delegate_AsyncEventHandler += Delegate_AsyncEventHandler_Event;
}
}

private Task Struct_AsyncEventHandler_Event(object? sender, AsyncEventArgs e)
private Task Struct_AsyncEventHandler_Event(CancellationToken ct)
{
return Task.CompletedTask;
}

private Task Delegate_AsyncEventHandler_Event(object? sender, AsyncEventArgs e)
private Task WeakAsyncEventHandler_Event(CancellationToken ct)
{
return Task.CompletedTask;
}

private Task Delegate_AsyncEventHandler_Event(object? sender, IAsyncEventArgs e)
{
return Task.CompletedTask;
}


private Task Struct_Call()
{
var args = new AsyncEventArgs();
return Struct_AsyncEventHandler.InvokeAsync(this, args);
return Struct_AsyncEventHandler.InvokeAsync();
}

private Task Weak_Call()
{
return WeakAsyncEventHandler.InvokeAsync();
}

private ValueTask Delegate_Call()
Expand All @@ -53,24 +69,30 @@ public async Task Struct_Call_1()
}

[Benchmark]
public async Task Delegate_Call_1()
public async Task Weak_Call_1()
{
await Delegate_Call();
await Weak_Call();
}

[Benchmark]
public async Task Struct_Call_100()
public async Task Delegate_Call_1()
{
for (int i = 0; i < 100; i++)
await Struct_Call();
await Delegate_Call();
}

[Benchmark]
public async Task Delegate_Call_100()
{
for (int i = 0; i < 100; i++)
await Delegate_Call();
}
//[Benchmark]
//public async Task Struct_Call_100()
//{
// for (int i = 0; i < 100; i++)
// await Struct_Call();
//}

//[Benchmark]
//public async Task Delegate_Call_100()
//{
// for (int i = 0; i < 100; i++)
// await Delegate_Call();
//}
}

}
29 changes: 29 additions & 0 deletions AsyncEventHandlers/AsyncEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Threading.Tasks;
using System.Threading;

namespace AsyncEventHandlers;

/// <summary>
/// The "action" delegate which should be supplied to the
/// <see cref="AsyncEventHandler{TEventData}.Register(AsyncEvent{TEventData})"/> and <see cref="AsyncEventHandler{TEventData}.Unregister(AsyncEvent{TEventData})"/>
/// methods.
/// <para/>
/// This shouldn't be used with the <see langword="event"/> keyword.
/// </summary>
/// <typeparam name="TEventData">Event data to pass to each subscriber.</typeparam>
/// <param name="data">An object that contains the event data.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to communicate cancellation of the async operation.</param>
/// <returns></returns>
public delegate Task AsyncEvent<in TEventData>(TEventData data, CancellationToken cancellationToken);

/// <summary>
/// The "action" delegate which should be supplied to the
/// <see cref="AsyncEventHandler.Register(AsyncEvent)"/> and <see cref="AsyncEventHandler.Unregister(AsyncEvent)"/>
/// methods.
/// <para/>
/// This shouldn't be used with the <see langword="event"/> keyword.
/// </summary>
/// <typeparam name="TEventData">Event data to pass to each subscriber.</typeparam>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to communicate cancellation of the async operation.</param>
/// <returns></returns>
public delegate Task AsyncEvent(CancellationToken cancellationToken);
26 changes: 14 additions & 12 deletions AsyncEventHandlers/AsyncEventArgs.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading;

namespace AsyncEventHandlers
namespace AsyncEventHandlers;

/// <summary>
/// The <see cref="CancellationToken"/> is automatically set.
/// </summary>
public interface IAsyncEventArgs
{
/// <summary>
/// The <see cref="CancellationToken"/> is automatically set.
/// </summary>
public class AsyncEventArgs : EventArgs
{
public CancellationToken CancellationToken { get; internal set; }
}
CancellationToken CancellationToken { get; internal set; }
}

/// <inheritdoc cref="IAsyncEventArgs" />
public class AsyncEventArgs : IAsyncEventArgs
{
public CancellationToken CancellationToken { get; set; }
}
Loading

0 comments on commit 95c2874

Please sign in to comment.