45 lines
1.3 KiB
C#
45 lines
1.3 KiB
C#
|
using System;
|
|||
|
using System.Linq;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
namespace SharedLibraryCore.Events;
|
|||
|
|
|||
|
public static class EventExtensions
|
|||
|
{
|
|||
|
public static Task InvokeAsync<TEventType>(this Func<TEventType, CancellationToken, Task> function,
|
|||
|
TEventType eventArgType, CancellationToken token)
|
|||
|
{
|
|||
|
if (function is null)
|
|||
|
{
|
|||
|
return Task.CompletedTask;
|
|||
|
}
|
|||
|
|
|||
|
return Task.WhenAll(function.GetInvocationList().Cast<Func<TEventType, CancellationToken, Task>>()
|
|||
|
.Select(x => RunHandler(x, eventArgType, token)));
|
|||
|
}
|
|||
|
|
|||
|
private static async Task RunHandler<TEventType>(Func<TEventType, CancellationToken, Task> handler,
|
|||
|
TEventType eventArgType, CancellationToken token)
|
|||
|
{
|
|||
|
if (token == CancellationToken.None)
|
|||
|
{
|
|||
|
// special case to allow tasks like request after delay to run longer
|
|||
|
await handler(eventArgType, token);
|
|||
|
}
|
|||
|
|
|||
|
using var timeoutToken = new CancellationTokenSource(Utilities.DefaultCommandTimeout);
|
|||
|
using var tokenSource =
|
|||
|
CancellationTokenSource.CreateLinkedTokenSource(token, timeoutToken.Token);
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
await handler(eventArgType, tokenSource.Token);
|
|||
|
}
|
|||
|
catch (Exception)
|
|||
|
{
|
|||
|
// ignored
|
|||
|
}
|
|||
|
}
|
|||
|
}
|