Question: what is the difference between this:
public Task NoAsyncAndAwait()
{
return client.SomeAsyncAPI();
}
and this
public async Task WithAsyncAndAwait()
{
await client.SomeAsyncAPI();
}
The first method simply returns the inner method, while the second one uses async
and await
to call the inner method.
One could argue that they both will result in the same thing. Which is true, to a certain degree.
But what does the compiler generate?
Let us use dnSpy to look at the generated code (since async and await gets compiled into "simpler" C# we can get a better understanding about what happens behind the screen...
The NoAsyncAndAwait
method, after decompiling with dnSpy looks like this:
// TaskVsAwaitTask.AsyncClient
// Token: 0x06000003 RID: 3 RVA: 0x00002068 File Offset: 0x00000268
public Task NoAsyncAndAwait()
{
return this.client.SomeAsyncAPI();
}
Nothing special here. But the WithAsyncAndAwait
method, which uses async
and await
looks like this:
// TaskVsAwaitTask.AsyncClient
// Token: 0x06000004 RID: 4 RVA: 0x00002088 File Offset: 0x00000288
[DebuggerStepThrough]
public Task WithAsyncAndAwait()
{
AsyncClient.<WithAsyncAndAwait>d__2 <WithAsyncAndAwait>d__ = new AsyncClient.<WithAsyncAndAwait>d__2();
<WithAsyncAndAwait>d__.<>4__this = this;
<WithAsyncAndAwait>d__.<>t__builder = AsyncTaskMethodBuilder.Create();
<WithAsyncAndAwait>d__.<>1__state = -1;
<WithAsyncAndAwait>d__.<>t__builder.Start<AsyncClient.<WithAsyncAndAwait>d__2>(ref <WithAsyncAndAwait>d__);
return <WithAsyncAndAwait>d__.<>t__builder.Task;
}
This method will result in the generation of a AsyncClient.<WithAsyncAndAwait>d__2
class which implements the workflow of this method. So, a lot more code gets generated.
Conclusion: Don't use async
and await
in this kind of scenario.