如何在等待异步委托在等待

2023-09-05 03:29:24 作者:没有你,姐依然潇洒

在MVA其中一个视频,我看到旁边建设:

In one of MVA videos i saw next construction:

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

执行结果将是:

Result of execution will be:

   In
   Press any key to continue . . .

这是完全编译,但现在我看不出有任何的方式来等待它。我可以把 Thread.sleep代码 Console.ReadKey 调用之后,但是这不是我想要的。

It's perfectly compiles, but right now i don't see any way to await it. I might put Thread.Sleep or Console.ReadKey after invocation, but that's not what i want.

那么如何委托应进行修改,以成为awaitable?(或者至少我怎么可以跟踪执行完毕?)

So how this delegate should be modified to become awaitable?(or at least how can i track that execution completed?)

时也有这样的代表任何实际的使用情况如何?

Is there are any practical usage of such delegates?

推荐答案

为了某事被期待已久的,它必须是 awaitable 。由于无效是不是这样,你不能期待任何动作委托。

In order for something to be awaited, it has to be awaitable. As void is not so, you cannot await on any Action delegate.

这是awaitable任何类型实现了 GetAwaiter 方法,该方法返回一个实现要么 INotifyCompletion 或类型 ICriticalNotifyCompletion ,像工作任务< T> ,例如

An awaitable is any type that implements a GetAwaiter method, which returns a type that implements either INotifyCompletion or ICriticalNotifyCompletion, like Task and Task<T>, for example.

如果你想等待一个代表,用Func键,这是一个等同于以下签名命名方式:

If you want to wait on a delegate, use Func, which is an equivalent to a named method with the following signature:

public Task Func()

因此​​,为了等待,改变你的方法:

So, in order to await, change your method to:

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

现在,你可以在它等待:

And now you can await on it:

await testFunc();