Every method async
should rather return a Task
- whether or not to wait for its end.
A method async
- beyond the obviousness of being an asynchronous method - it means that a new Thread
to perform its action. And for you to have control of the life cycle of this task, your method returns a type Task
so that you can know when this task is over, if you want to finish with its execution or even to know what it has returned.
The problem of creating a method async void
is that there is no such control, and the execution of this task can be completed 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 sending the email 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, upon returning, the Task
- that exists, but just hasn’t been returning, 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.
There will be no return of the method async void
, because he had his cancellation forced by the end of his "summoner" - the method Main()
.
Related https://answall.com/q/148940/2541
– ramaral
Related link https://github.com/dotnet/roslyn/issues/13897
– vinibrsl