How to wait for async void to complete?

2019-09-25 01:23发布

问题:

i need to wait for my async void to finish. It has some await Task.Delay functions in it and I need them to finish before it continues. This void doesn't return anything so I don't see a reason to make it async Task<> and I also shuffle an array inside this void and I declare some variables. So how can I do this ? Is async Task<> the only way ? My void is not expecting any parameters/inputs.

回答1:

Return Task (not Task<T>) instead of void. Note, the non-generic form of Task does not need to wrap a value. It's just for signalling completion or errors, not results. In the case of async methods, this is equivalent to a synchronous void return type. It means you can wait for your method to complete.



回答2:

Every async function should return Task instead of void and Task<TResult> instead of TResult. The only exception of this is the event handler.

So if your async function isn't an event handler it should return Task. Once this is done you can await for it...

... ehm, provided that your function is also declared async and returns Task or Task<TResult>, which makes that your clients all must be async.

If you have a sync function and want to call an async function use the following:

var myTask = Task.Run( () => SomeAsyncFunction(...));
// while my task is running you can do other things
// after a while you need the result:
Task.Wait();

// only if SomeAsyncFunction returns Task<TResult>:
TResult result = Task.Result();

Be aware though that this will halt your function until the task is finished. So when possible consider making your function also async. The code would be like:

public async void Button1_Clicked(object Sender, ...)
{
    var task = MySlowMultiplier(3, 4);
    // while task running you can do other things
    // the UI remains responsive
    // after a while:
    int result = await task;
    ProcessResult(result);
 }

 private async Task<int> MySlowMultiplier(int x, int y)
 {
     // I'm really slow:
     await Task.Delay(TimeSpan.FromSeconds(5));
     return x * y;
 }


回答3:

You can use this code.

var result = Task.Run(async() => { return await METHODNAMEHERE(); }).Result;