does last async call in async method require await?

余生颓废 提交于 2021-02-05 05:18:26

问题


I can't understand if await statement is required when async method call is the last call in my async method. E.g.

public async Task CallAsync(byte[] data)
{
    await Call1Async(data);
    Call2Async(data);
}

public async Task Call1Async(byte[] data)
{
   ...
}

public async Task Call2Async(byte[] data)
{
   ...
}

The above would compile but with a warning "consider applying await to this method". But I think it would be waste of resources to apply await for the last call in the method.

At the same time, if I use return Call2Async(data); instead of just Call2Async(data);, the warning would go away. This indicates await is not actually required in such situation.

But this only works for methods which have a return value (i.e. Task<T> rather than just Task). I need this for methods without return values. Is there any way to do the same for value-returning methods?

I.e. I need to somehow return Task object returned by Call2Async to the caller of CallAsync and I can't use return statement in CallAsync explicitly as my methods don't have return values. Of course, I can adjust them all to return values (e.g. true) but it would not be an elegant solution.

P.S. If I have the only async call in my method, I just don't add 'async' to the method signature, and it works ('return' statement not required). But if the method contains more than one async call, I need to have 'async' modifier to be able to await for the first call 'await Call1Async(data)'. And adding 'async' modifier makes the compiler require 'return' to return Task object to the caller (and this works only for methods with return values). That's what I'm trying to overcome.


回答1:


In the following method:

public async Task CallAsync(byte[] data)
{
    await Call1Async(data);
    Call2Async(data);
}

Control from the method returns after beginning Call2Async. That is, if you were to await CallAsync(data), it would finish before Call2Async ends. This is probably not what you intended. This method will only finish when both calls are complete:

public async Task CallAsync(byte[] data)
{
    await Call1Async(data);
    await Call2Async(data);
}

You can see the difference in these example outputs (I implemented the two async calls to simply print a start, delay for a second, and then print an end).

void Main()
{
    Console.WriteLine("Main start");
    CallAsync(null).Wait();
    Console.WriteLine("Main end");
}

The method without the second await prints:

Main start
Call1Async start
Call1Async end
Call2Async start
Main end
Call2Async end

And with the second await:

Main start
Call1Async start
Call1Async end
Call2Async start
Call2Async end
Main end

This implementation also has a problem:

public Task CallAsync(byte[] data)
{
    Call1Async(data);
    return Call2Async(data);
}

It kicks off both async calls at the same time, but then returns control when Call2Async completes, whether Call1Async is complete or not. Again, this is probably not what you intended.




回答2:


async keyword indicates that the method is asynchronous and than it will contain the await keyword in it. I don't understand why you have multiple asynchronous methods?

Consider the following example :

async void MyMethod()
{
Task<object> result = MyWorkAsync();

MyIndependentOtherWork();

object res = await result;
}

Calling MyWorkAsync is like creating a thread "toto" to execute the method (i.e Thread.Start(MyWorkAsyn))

The await keyword is like making a join form the current thread to the thread "toto" and than getting the result of "toto", and in the mean time you get your other independent work to execute on the current thread



来源:https://stackoverflow.com/questions/20287429/does-last-async-call-in-async-method-require-await

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!