.net - What is the purpose of "return await" in C#?

ID : 10457

viewed : 20

Tags : c#.net.net-4.5async-awaitc#

Top 5 Answer for .net - What is the purpose of "return await" in C#?

vote vote

94

There is one sneaky case when return in normal method and return await in async method behave differently: when combined with using (or, more generally, any return await in a try block).

Consider these two versions of a method:

Task<SomeResult> DoSomethingAsync() {     using (var foo = new Foo())     {         return foo.DoAnotherThingAsync();     } }  async Task<SomeResult> DoSomethingAsync() {     using (var foo = new Foo())     {         return await foo.DoAnotherThingAsync();     } } 

The first method will Dispose() the Foo object as soon as the DoAnotherThingAsync() method returns, which is likely long before it actually completes. This means the first version is probably buggy (because Foo is disposed too soon), while the second version will work fine.

vote vote

90

If you don't need async (i.e., you can return the Task directly), then don't use async.

There are some situations where return await is useful, like if you have two asynchronous operations to do:

var intermediate = await FirstAsync(); return await SecondAwait(intermediate); 

For more on async performance, see Stephen Toub's MSDN article and video on the topic.

Update: I've written a blog post that goes into much more detail.

vote vote

80

The only reason you'd want to do it is if there is some other await in the earlier code, or if you're in some way manipulating the result before returning it. Another way in which that might be happening is through a try/catch that changes how exceptions are handled. If you aren't doing any of that then you're right, there's no reason to add the overhead of making the method async.

vote vote

70

Another case you may need to await the result is this one:

async Task<IFoo> GetIFooAsync() {     return await GetFooAsync(); }  async Task<Foo> GetFooAsync() {     var foo = await CreateFooAsync();     await foo.InitializeAsync();     return foo; } 

In this case, GetIFooAsync() must await the result of GetFooAsync because the type of T is different between the two methods and Task<Foo> is not directly assignable to Task<IFoo>. But if you await the result, it just becomes Foo which is directly assignable to IFoo. Then the async method just repackages the result inside Task<IFoo> and away you go.

vote vote

50

If you won't use return await you could ruin your stack trace while debugging or when it's printed in the logs on exceptions.

When you return the task, the method fulfilled its purpose and it's out of the call stack. When you use return await you're leaving it in the call stack.

For example:

Call stack when using await: A awaiting the task from B => B awaiting the task from C

Call stack when not using await: A awaiting the task from C, which B has returned.

Top 3 video Explaining .net - What is the purpose of "return await" in C#?

Related QUESTION?