Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

await Task.CompletedTask for what?

I created UWP app with Windows Template Studio that introduced at Build2017.

Below class is a part of generated code from it.

public class SampleModelService {     public async Task<IEnumerable<SampleModel>> GetDataAsync()     {         await Task.CompletedTask; // <-- what is this for?         var data = new List<SampleModel>();          data.Add(new SampleModel         {             Title = "Lorem ipsum dolor sit 1",             Description = "Lorem ipsum dolor sit amet",             Symbol = Symbol.Globe         });          data.Add(new SampleModel         {             Title = "Lorem ipsum dolor sit 2",             Description = "Lorem ipsum dolor sit amet",             Symbol = Symbol.MusicInfo         });         return data;     } } 

My question is, what is the purpose and reason of await Task.CompletedTask; code in here? It actually does not have Task result receiver from it.

like image 901
Youngjae Avatar asked May 21 '17 11:05

Youngjae


People also ask

What is the use of task CompletedTask?

Task. CompletedTask property is important when you need to give a caller a dummy Task (that doesn't return a value/result) that's already completed. This might be necessary to fulfill an "interface" contract or testing purposes.

What exactly does await do?

The await operator suspends evaluation of the enclosing async method until the asynchronous operation represented by its operand completes. When the asynchronous operation completes, the await operator returns the result of the operation, if any.

What happens if you dont await task?

If you don't await the task or explicitly check for exceptions, the exception is lost. If you await the task, its exception is rethrown. As a best practice, you should always await the call. By default, this message is a warning.

What is the point of await async?

Note: The purpose of async / await is to simplify the syntax necessary to consume promise-based APIs. The behavior of async / await is similar to combining generators and promises. Async functions always return a promise.


1 Answers

It is there to make it easier for later stage to implement async code calls without having to alter the signature thus preventing having to refactor the calling code.

Whilst the scaffolded sample code is synchronous, the Template Studio is designed specifically around an async data access layer, you are expected to implement your own data access by modifying the body of the generated methods.

If the async implementation were NOT implemented, there would be significant code changes throughout the templated app and it would be a very steep learning curve for new developers, the point of the template is to get up and running with minimal effort or even experience!

Another option would be to remove the async keyword from the method signature and that line and do

return Task.FromResult<IEnumerable<SampleModel>>(data);  

You see this construct when you need to return an awaitable Task due to an interface for example while the implementation has no async work to do.

In this case however, since it is a template they expect people to replace the await Task.Completed with something like await FetchDataFromDatabaseAsync();. Since the async keyword is already there it minimizes the needed changes to implement your own async call.

Anyway, without this await construct you can do this:

public class SampleModelService {     public Task<IEnumerable<SampleModel>> GetDataAsync()     {         var data = new List<SampleModel>();          data.Add(new SampleModel         {             Title = "Lorem ipsum dolor sit 1",             Description = "Lorem ipsum dolor sit amet",             Symbol = Symbol.Globe         });          data.Add(new SampleModel         {             Title = "Lorem ipsum dolor sit 2",             Description = "Lorem ipsum dolor sit amet",             Symbol = Symbol.MusicInfo         });          return Task.FromResult<IEnumerable<SampleModel>>(data);       } } 

If there is no requirement to return a Task at all (you do not have any async code) then just remove it completely. (But then you have to refactor code that calls this method)

Reviewing this code I suspect someone is going to call an async method later in the development process and already anticipated that by specifying that this method returns a Task.

like image 77
Peter Bons Avatar answered Sep 27 '22 22:09

Peter Bons