Is there any difference between the methods below? Is one preferable over the other?
public static async Task SendAsync1(string to, string subject, string htmlBody) {
// ...
await smtp.SendMailAsync(message);
// No return statement
}
public static Task SendAsync2(string to, string subject, string htmlBody) {
// ...
return smtp.SendMailAsync(message);
}
This method will be called from MVC controller methods; for example:
public async Task<ActionResult> RegisterUser(RegisterViewModel model)
{
// ...
await Mailer.SendAsync(user.Email, subject, body);
return View(model);
}
The only time we truly want to await is when we do something with the result of the async task in the continuation of the method. Note that if we don't have return await, but return a Task<T> instead, the return happens right away, so, if the code is inside a try/catch block, the exception will not be caught.
Async methods can have the following return types: Task, for an async method that performs an operation but returns no value. Task<TResult>, for an async method that returns a value. void , for an event handler.
Async methods are intended to be non-blocking operations. An await expression in an async method doesn't block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method.
The behavior of async / await is similar to combining generators and promises. Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.
There are 2 practical differences:
async-await
usage. That will have a minor positive effect on performance.async
any exceptions are stored in the returned task (both from the asynchronous part and the synchronous one) and thrown only when the task is awaited (or waited). When it's not async
, the exceptions from the synchronous parts act just like in any other method.My suggestion: Use the second one for the added performance boost but keep an eye out for exceptions and bugs.
An example that shows the difference:
public static async Task Test()
{
Task pending = Task.FromResult(true);
try
{
pending = SendAsync1();
}
catch (Exception)
{
Console.WriteLine("1-sync");
}
try
{
await pending;
}
catch (Exception)
{
Console.WriteLine("1-async");
}
pending = Task.FromResult(true);
try
{
pending = SendAsync2();
}
catch (Exception)
{
Console.WriteLine("2-sync");
}
try
{
await pending;
}
catch (Exception)
{
Console.WriteLine("2-async");
}
}
public static async Task SendAsync1()
{
throw new Exception("Sync Exception");
await Task.Delay(10);
}
public static Task SendAsync2()
{
throw new Exception("Sync Exception");
return Task.Delay(10);
}
Output:
1-async
2-sync
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With