首页 > 解决方案 > 为什么分配异步等待事件处理程序不会导致任何问题?

问题描述

给定以下代码:

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;
}

我想知道为什么这不会引起任何问题。不async () => await AsyncHandler()返回任务?在此示例中,它可以分配给返回 void? 的委托。

另外,这会导致任何问题吗?使偶数处理程序异步......那么容易吗?我想知道在这种情况下可能会在哪里捕获潜在的异常。

为了比较,上面示例中的以下代码:

var tasks = Enumerable.Range(0, 5).Select(async _ => await AsyncHandler());

await Task.WhenAll(tasks);

正如预期的那样,这会产生一个Task. 那么为什么它现在是一个任务,但在它之上算作无效呢?

标签: c#.net

解决方案


在这段代码中:

TestEvent += async () => await AsyncHandler();

...编译器正在推断 lambda 表达式的类型。它推断出与委托匹配的类型。它或多或少与这样做相同:

var action = new Action(async () => await AsyncHandler());  //<-- not a Func<Task>!
TestEvent += action;

您会注意到您没有为事件分配功能,而是为操作分配。

如果您想知道如何从函数中推断出动作,请参阅为什么 lambdas 可以将函数调用转换为动作?.


推荐阅读