Reputation: 985
I know similar questions have been asked, but I'm struggling with the concepts of asynchronous programming in .net. As a web developer, I understood how calling functions asynchronously didn't cause the UI to block and you could do other things. But now I'm on the other side, writing a C# Web API service to retrieve information from a database and do some calculations. I made the functions in the controller async by adding the async keyword to the function header, which I naively thought would be the end of it, but then it tells me I need to use the await keyword in the function. So I figured out how to do that (I have read a lot by this point) but I don't get WHY I need to do that, as well as WHEN. Like say I have a web method like below where it calls two other functions but only one is called with await. Is that bad? Will it only be non-blocking part of the time? I then made another test function that has no await keyword and it worked fine (bottom code).
[HttpPost]
public async Task<IHttpActionResult> CalculateBMIAsync([FromBody]MeasureInput patientData)
{
string results = String.Empty;
MeasureReturn returnVal = null;
try
{
string msgInvalid = await Translators.validatePatMonthXML(patientData);
if (String.IsNullOrEmpty(msgInvalid))
{
results = await measureProcessor.CalculateBMI(patientData);
}
else
return new BadRequestWithInfoResult(Translators.CreateErrorXML(new Exception(msgInvalid)));
}
catch (Exception ex)
{
return new BadRequestWithInfoResult(Translators.CreateErrorXML(ex));
}
return Ok<MeasureReturn>(returnVal);
}
Example web API method that worked asynchronously when called with jquery (no await used here):
[HttpPost]
public async Task<IHttpActionResult> CalculateTest()
{
long d = 0;
for (long i = 0; i < 2000000000; i++)
{
d = i;
}
string returnVal = d.ToString();
return Ok(returnVal);
}
Calling code:
$('#btn1').click(function () {
console.log('Ajax request');
$.ajax({
url: 'http://localhost:53312/api/Measures/CalculateTest',
type: 'POST',
success: function (data) {
$('#result1').html('async request finished');
}
})
});
Upvotes: 0
Views: 1806
Reputation: 218798
In the context of a web application endpoint (API endpoint, controller action, etc.) don't necessarily think of it as "not blocking the UI". Instead, think of it as "not tying up a web server thread". Consider a web service which performs some I/O with disks or other systems. By making these I/O operations async, the web server is free to receive/handle more requests while those I/O operations are invoked.
You would almost always await asynchronous operations. The only times you wouldn't are when you really know what you're doing. When your code here is awiting something, what it's doing it ensuring that operation completes before moving on to the next line of code. This is probably a good thing. Especially if that next line of code needs something which was performed by that asynchronous operation.
If your controller or API method internally invoked asynchronous operations, await them. If it doesn't invoke any then it itself doesn't need to be async.
*Note: A lot of times people will, often naively, not await an asynchronous operation because they want it to be "fire and forget". Just remember the "forget" part of that. "Forget" means "I don't care if this operation even succeeds or not."
Sometimes that might be okay. Most of the time it isn't. If you want to ensure the result of the operation, await it. Let the top-level application layer worry about the UI.
Upvotes: 5
Reputation: 413
I'll try to make this distinction without getting to technical. Basically, if you care what the return value is.. await. Otherwise... your call. But without the await it's just a task.
For instance, I write a function to calculate taxes, without the await, I have no return value, thus a failure. With the await(it's not the only way), I get back my answer of say .25 If you are still stuck, let me know.
Upvotes: 1