Every method async
should instead return a Task
- regardless of whether or not it will wait for its end.
A async
method - in addition to the obviousness of being an asynchronous method - means that a new Thread
will be created to perform its action. And for you to have control over the lifecycle of that task, your method returns a type Task
so you can know when this task is finished, whether you want to end its execution or even to know what it has returned. / p>
The problem of creating a async void
method is that this control does not exist, and the execution of that task may be terminated before the end of its execution. See the example:
public async Task EnviarEmailAsync()
{
// ação para envio do email
// normalmente é demorado, leva mais que 100ms por exemplo.
return;
}
To consume, we do:
await EnviarEmailAsync();
return;
This will ensure that your code will wait for the email to be sent before returning.
Now using an example without returning a Task
:
public async void EnviarEmailAsync()
{
// ação para envio do email
// normalmente é demorado, leva mais que 100ms por exemplo.
return;
}
To consume, we do:
EnviarEmailAsync();
return;
In this case, when returning, the Task
- that exists, but only did not return, and there are no references to it - will be canceled.
You can test this in this example in .NET Fiddle .
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
public static void Main()
{
Task.Run(async () =>
{
Console.WriteLine("Inicio de envio de emails.");
await EnviarEmailAsync();
EnviarEmail();
Console.WriteLine("Fim de execução.");
}).Wait();
}
public static async Task EnviarEmailAsync()
{
await Task.Run(() => Thread.Sleep(500)); // simula envio de email, que dure 500ms
Console.WriteLine("Email A enviado.");
}
public static async void EnviarEmail()
{
await Task.Run(() => Thread.Sleep(500)); // simula envio de email, que dure 500ms
Console.WriteLine("Email B enviado.");
}
}
The result will be:
> Inicio de envio de emails.
> Email A enviado.
> Fim de execução.
It will not return the async void
method, as it has been forced to terminate at the end of its "invocator" - the Main()
method.