First of all, I see that you’re confusing asymchronism with parallelism, even though the two are closely related, one is very different from the other.
When programming asynchronously, the task shall provide a feedback mechanism, normally a delegate as in the example below.
private delegate void NotificacaoIosTodos(string titulo, int posicao, int unidadeId);
public void MinhaAction()
{
var argumentos = new object[] { titulo, configuracaoItem.Posicao, unidade.UnidadeAtual };
var notificacao = new NotificacaoIosTodos(_notificacaoController.NotificacaoIosTodos, argumentos);
notificacao.BeginInvoke(new AsyncCallback(NotificacoesCallback), notificacao);
}
public void NotificacoesCallback()
{
DoSomething();
}
the example above the NotificacoesCallback will be called as soon as the NotificacaoIosTodos conclusion, not allocating any additional resource between the call of the MinhaAction and NotificacoesCallback.
Parallelism has the function of performing tasks simultaneously. One way to achieve this is to create a new Task, remembering that you may or may not wait for the return of the same.
public void MinhaAction()
{
var notificacao = Task.Run(() => _notificacaoController.NotificacaoIosTodos(titulo, configuracaoItem.Posicao, unidade.UnidadeAtual));
notificacao.Wait();
DoSomething();
}
In the above example, a new Task. By calling the Wait you will be blocking the Thread current, so it is very likely that you are allocating more resources than is necessary.
The scenario is something that should be avoided, but the conditions below can bring some gain.
Example 1
public void MinhaAction()
{
var notificacao = Task.Run(() => _notificacaoController.NotificacaoIosTodos(titulo, configuracaoItem.Posicao, unidade.UnidadeAtual));
// DoSomething1 é executado ao mesmo tempo que NotificacaoIosTodos;
DoSomething1();
// Aqui a Thread atual é bloqueada até a conclusão de NotificacaoIosTodos
notificacao.Wait();
// Por fim é executado DoSomething2
DoSomething2();
}
Example 2
public void MinhaAction()
{
var notificacoes = new Task[10];
for (var posicao = 0; posicao < notificacoes.Length; posicao++)
notificacoes[posicao] = Task.Run(() => _notificacaoController.NotificacaoIosTodos(titulo, posicao, unidade.UnidadeAtual));
// As 10 notificações serão executadas em paralelo enquanto a Thread atual é bloqueada.
Task.WaitAll(notificacoes);
// Por fim é executado DoSomething2
DoSomething();
}
Now let’s go back to asymchronism in this case using the reserved words async/await
public async Task MinhaAction()
{
await _notificacaoController.NotificacaoIosTodos(titulo, configuracaoItem.Posicao, unidade.UnidadeAtual);
DoSomething();
}
internal async Task NotificacaoIosTodos(string titulo, int posicao, int unidadeId)
{
await ConsultaBancoDeDados();
}
In the above example, a new thread will not be created. By calling NotificacaoIosTodos it will be synchronized within the current context. This behavior is quite useful when we need to do some I/O operation, such as reading a file or consulting the database.
On the other hand, if we’re gonna do any surgery CPU Bound, then it is interesting that this process runs in a Thread separated as the Thread is released, for such we make use of the Task.Run.
public async Task MinhaAction()
{
await Task.Run(() => _notificacaoController.NotificacaoIosTodos(titulo, configuracaoItem.Posicao, unidade.UnidadeAtual));
DoSomething();
}
internal async Task NotificacaoIosTodos(string titulo, int posicao, int unidadeId)
{
await CalcularHashCemMilVezes();
}
now a small matching example asymchronism with parallelism:
public async Task MinhaAction()
{
var notificacoes = new Task[10];
for (var posicao = 0; posicao < notificacoes.Length; posicao++)
notificacoes[posicao] = _notificacaoController.NotificacaoIosTodos(titulo, posicao, unidade.UnidadeAtual);
// As 10 notificações serão executadas em paralello enquanto a Thread atual é bloqueada.
await Task.WhenAll(notificacoes);
// Por fim é executado DoSomething2
DoSomething();
}
internal async Task NotificacaoIosTodos(string titulo, int posicao, int unidadeId)
{
await ConsultaBancoDeDados();
}
And as for the async void, avoid using it unless the method is a method fire and Forget, as a evento or a method that its completion is not expected by another method (such as an email sending).
And finally, despite the Task.Run do not make execution asynchronous, it is possible to use the method ContinueWith to add a return mechanism to the Task.
public async Task MinhaAction()
{
var notificacao = await Task.Run(() => _notificacaoController.NotificacaoIosTodos(titulo, configuracaoItem.Posicao, unidade.UnidadeAtual));
notificacao.ContinueWith(task => {
// task.Result possui o retorno de NotificacaoIosTodos
DoSomething(task.Result);
}, TaskContinuationOptions.OnlyOnRanToCompletion);
notificacao.ContinueWith(task => {
LogarErro(task.Exception.Message);
}, TaskContinuationOptions.OnlyOnFaulted);
}
internal async Task<bool> NotificacaoIosTodos(string titulo, int posicao, int unidadeId)
{
return await ConsultaBancoDeDados();
}
Yes, the way it’s being used(through
Task.Run()) it will be executed asynchronously. Regarding the use ofasyncandawaitsee this reply– ramaral
I had read a little about the async and await, the problem is in this case the same as mine that I don’t know if I would need the async or if the Task.run ()) would make it asynchronous even calling a method that is not marked as async, I will read the answer soon, thank you very much for the tip.
– William Cézar
What makes the execution of the method
NotificacaoIosTodos()asynchronous is the use ofTask.Run(). The purpose ofawaitis to facilitate the "integration/interaction" of asynchronous code (Task’s) with synchronous code, allowing the code to maintain a structure similar to synchronous code.asyncis necessary if you want to useawaitin a method.– ramaral
I edited the question based on the @ramaral comment that is right to say that what makes the method execution
NotificacaoIosTodos()asynchronous is the use ofTask.Run(). I put the documentation link that proves that his comment is correct.– George Wurthmann
@Georgewurthmann for years MS misused the word
asynchronousin its documentation, because it used it when it wanted to sayexecutar uma thread em background.– Tobias Mesquita
@Tobiasmesquita then the documentation is wrong to say that the work will be run asynchronously? Will it be just in a thread? I changed the answer after I saw it in the documentation.
– George Wurthmann
@Georgewurthmann take a look at this article: Task.Run Etiquette Examples you will understand a little better the functioning of
Task.Run.– Tobias Mesquita