Given the following code:
delegate void TestEventHandler();
event TestEventHandler TestEvent;
void Main()
{
TestEvent += () => Console.WriteLine("Sync");
TestEvent += async () => await AsyncHandler();
TestEvent();
}
private async Task<int> AsyncHandler()
{
await Task.Delay(200);
Console.WriteLine("Async");
return 5;
}
I'd like to know why this does not cause any problems. Doesn't async () => await AsyncHandler() return a Task? In this example it is assignable to a delegate returning void?
Also, does this cause any problems? Is making an even handler async... that easy? I'm wondering where a potential exception might be caught in this case.
For comparison, the following code in the above sample:
var tasks = Enumerable.Range(0, 5).Select(async _ => await AsyncHandler());
await Task.WhenAll(tasks);
This produces, as expected, a collection of Task. So why is it a Task now, but above it counts as void?
In this code:
TestEvent += async () => await AsyncHandler();
...the compiler is inferring the type of the lambda expression. It infers a type that matches the delegate. It is more or less the same as doing this:
var action = new Action(async () => await AsyncHandler()); //<-- not a Func<Task>!
TestEvent += action;
You'll notice that you are not assigning a function to the event but an action.
If you're wondering how an action can be inferred from a function, see Why can lambdas convert function calls into actions?.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With