How to await on async delegate

2019-03-10 18:14发布

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("After first delay");
        await Task.Delay(100);
        Console.WriteLine("After second delay");
    };

    testAction.Invoke();
}

Result of execution will be:

In
Press any key to continue . . .

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.

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?

3条回答
Ridiculous、
3楼-- · 2019-03-10 19:07

Recently I found that NUnit able to await async voidtests. Here is good description how it works: How does nunit successfully wait for async void methods to complete?

You won't use it in regular tasks, but it's good to know that it is possible

查看更多
ら.Afraid
4楼-- · 2019-03-10 19:10

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

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.

If you want to wait on a delegate, use Func<Task>, 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 it:

await testFunc();
查看更多
登录 后发表回答