3

So I have a question about Task and async/await operation.

I have a method like this:

public Task<IActionResult> PostCompleteFormModel(string name, [FromBody]IndicatorFormApi apiModel, Guid participantId, [FromServices] IChallengeCycleService challengeCycleService)
{
    return Post(name, apiModel.ToSubmitApi(), participantId, challengeCycleService);
}

in a controller.

And as you can see it is without async/await.

But is it not better to do it like this:

public async Task<IActionResult> PostCompleteFormModel(string name, [FromBody]IndicatorFormApi apiModel, Guid participantId, [FromServices] IChallengeCycleService challengeCycleService)
{
    return await Post(name, apiModel.ToSubmitApi(), participantId, challengeCycleService);
}

So with the async/await keywords?

Or doesn't make it a differ?

Thank you

Vita
  • 3
  • 1
  • The first model is better. See the answers [here](https://stackoverflow.com/q/21033150/3602352) and [here](https://stackoverflow.com/q/38017016/3602352) for comprehensive explanations. – Aly Elhaddad Jan 20 '20 at 12:33
  • 3
    https://blog.stephencleary.com/2016/12/eliding-async-await.html – Matthew Watson Jan 20 '20 at 12:37

2 Answers2

13

Both methods are asynchronous, but they have slightly different semantics. Specifically, they will behave differently if ToSubmitApi throws an exception.

The async keyword creates a state machine, which is responsible for managing the returned Task. If the code in an async method throws an exception, then the async state machine captures that exception and places it on the returned Task. This is the expected semantics for a method that returns Task.

Without the async keyword, the method would call ToSubmitApi and then call Post and return the Task returned from Post. So if ToSubmitApi threw an exception, that exception would be raised directly to the caller rather than being placed on the returned Task. These semantics are not expected.

As a general rule, I recommend keeping the async and await keywords unless the method is trivial and will not throw an exception. E.g., overloads that essentially supply default argument values. In this specific case, ToSubmitApi is a separate method that could possibly throw (or could be changed in the future to throw), so I recommend keeping the async and await keywords.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • Oke, but what exactly is the benefit of this then? "So if ToSubmitApi threw an exception, that exception would be raised directly to the caller rather than being placed on the returned Task" –  Jan 20 '20 at 16:22
  • @niceCoderToTheBest: The only benefit to eliding `async` and `await` is a minor performance increase, since there is not an additional stack machine. – Stephen Cleary Jan 20 '20 at 16:29
  • Oke, understand. But what do you mean with eliding? or is that a type? –  Jan 20 '20 at 16:31
  • @niceCoderToTheBest: "elide" means "to leave something out". So eliding `async` and `await` is to write an asynchronous method without `async` and `await`. – Stephen Cleary Jan 20 '20 at 16:43
-1

By adding "async/await" you are allowing the application for not blocking the caller thread which inturns increase the throughput of the method as it will become asynchronous. Without async/await (or not making asynchronous) the method you have would be synchronous, which means the second caller has to wait until the first caller completes the execution (If single-threaded asynchronous) as the first caller blocks the thread until it completes the execution.

One thing to keep in mind in async/await won't improve the application performance but it will increase the throughput of the application so the next request doesn't need to wait until the last one has completed. For example, say your method takes 5 seconds to complete the execution but adding async/await won't reduce the execution time but it will allow multiple requests to process in 5 seconds. Say you have 3 requests to handle at the exact same time then without async/await each takes 5 seconds, which means to complete all requests it will take 15 seconds. By adding async/await all three requests completes in 5 seconds (hypothetically).

Vijayanath Viswanathan
  • 8,027
  • 3
  • 25
  • 43
  • I have one more question. But what is the purpose of Task then? So without async/await –  Jan 20 '20 at 13:21