Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a pass-through async method really need the await/async pattern? [duplicate]

Let's say I have an method that calls another async method immediately or similar:

//Main method
public async Task<int> Foo1( int x )
{
     var result = await DoingSomethingAsync(x );
     return DoSomethingElse(result );
}  
//other method
public async Task<int> Foo2( Double double )
{
     return await Foo1( Convert.ToInt32(double ) );
}  

Is there any specific reason that Foo2 needs/should have async/await, as opposed to simply calling:

//other method
public Task<int> Foo3( Double double )
{
     return Foo1( Convert.ToInt32( double ) );
}  

In a consumer, this would still be awaited, likeso, regardless of:

int x = await Foo1(1);
int x = await Foo2(1D);
int x = await Foo3(1D);

All those statements will compile. Will the compiler generate different IL for the two different methods?

like image 409
James Haug Avatar asked Feb 15 '17 18:02

James Haug


1 Answers

It depends. In particular, the exception behavior is different if Convert.ToInt32 throws.

I have a whole blog post on the subject, but in summary, I would use async/await here because the exception would be placed on the returned task. Otherwise, the exception would be thrown directly.

Throwing exceptions directly is only acceptable for precondition exceptions (i.e., it's a violation of the API to pass a double that can't be converted to an int). And even then (for precondition exceptions) you can choose to either throw exceptions directly or place them on the returned task.

like image 93
Stephen Cleary Avatar answered Sep 28 '22 03:09

Stephen Cleary