C# 如何等待异步委托

C# 如何等待异步委托,c#,.net,asynchronous,async-await,C#,.net,Asynchronous,Async Await,在一个MVA视频中,我看到了下一个构造: static void Main(string[] args) { Action testAction = async () => { Console.WriteLine("In"); await Task.Delay(100); Console.WriteLine("After first delay"); await Task.Delay(100);

在一个MVA视频中,我看到了下一个构造:

static void Main(string[] args)
{
    Action testAction = async () =>
    {
        Console.WriteLine("In");
        await Task.Delay(100);
        Console.WriteLine("After first delay");
        await Task.Delay(100);
        Console.WriteLine("After second delay");
    };

    testAction.Invoke();
}
执行结果将是:

In
Press any key to continue . . .
这是完美的编译,但现在我看不到任何方式等待它。我可能会在调用后放置
Thread.Sleep
Console.ReadKey
,但这不是我想要的

那么该如何修改此委托以使其成为可等待的?(或者至少我该如何跟踪已完成的执行?)

此类委托是否有实际用途?

“Async void仅适用于顶级事件处理程序”


为了等待某些东西,它必须是可等待的。由于
void
并非如此,您不能等待任何
操作
委托

等待是实现
GetAwaiter
方法的任何类型,该方法返回实现
INotifyCompletion
ICriticalNotifyCompletion
的类型,例如
Task
Task

如果要等待委托,请使用
Func
,这相当于具有以下签名的命名方法:

public Task Func()
因此,为了等待,请将方法更改为:

static void Main(string[] args)
{
    Func<Task> testFunc = async () =>
    {
        Console.WriteLine("In");
        await Task.Delay(100);
        Console.WriteLine("First delay");
        await Task.Delay(100);
        Console.WriteLine("Second delay");
    };
}

最近我发现NUnit能够等待
异步void
测试。以下是其工作原理的详细说明:


您不会在常规任务中使用它,但最好知道它是可能的

没有办法等待它。如果它是
Func
,则会有所不同。这就是为什么应该避免使用
async void
,最好只在顶级事件处理程序中使用。您可能会发现这很有帮助。
await testFunc();