'EventHandler with Task as return value
The base C# EventHandler is defined as:
namespace System
{
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
}
Does anyone if there is an awaitable event handler available? E.g.
public delegate Task EventHandlerAsnyc<TEventArgs>(object sender, TEventArgs e);
Thx
Solution 1:[1]
The downside of just using async void handlers is that there is no way for the caller to wait for the result. This may be an issue for some interactive event handlers, like the ones using CancelEventArgs.
But you can still declare a Task-returning delegate type, if you wish. You just have to be careful how you raise it then. For instance, you could make an extension method which you can call as handler.Raise(sender, EventArgs.Empty).
public delegate Task EventHandlerAsnyc<TEventArgs>(object sender, TEventArgs eventArgs);
public static async Task Raise<TEventArgs>(this EventHandlerAsnyc<TEventArgs> handlers, object sender, TEventArgs eventArgs)
{
if (handlers == null)
return;
foreach (var handler in handlers.GetInvocationList())
await ((EventHandlerAsnyc<TEventArgs>)handler).Invoke(sender, eventArgs);
}
Alternatively, you can allow handlers to execute concurrently. But this would probably be a bad idea unless well-documented, as it's probably considered surprising behavior.
public static Task RaiseAllowConcurrent<TEventArgs>(this EventHandlerAsnyc<TEventArgs> handlers, object sender, TEventArgs eventArgs)
{
if (handlers == null)
return Task.CompletedTask;
var invocationList = handlers.GetInvocationList();
var tasks = new Task[invocationList.Length];
for (var i = 0; i < invocationList.Length; ++i)
tasks[i] = ((EventHandlerAsnyc<TEventArgs>)invocationList[i]).Invoke(sender, eventArgs);
return Task.WhenAll(tasks);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | relatively_random |
