Porque é importante?

Como todos sabem, Programação Assíncrona é muito importante porque tem como objetivo principalmente aperfeiçoar a capacidade de resposta de nossas aplicações. O .NET sempre tem tentando apoiar esta forma desde sua primeira versão e sempre houveram novos recursos em cada release e apresentações de novas maneiras de assincronismo. Todas estas funcionalidades estão fora do escopo deste artigo, mas aqui estão vários recursos falando com detalhes sobre eles e descrevendo o seu uso com detalhes.
No entanto, nós desenvolvedores costumamos escrever métodos, eu digo métodos síncronos e tentamos chama-los assincronamente, de várias maneiras (Thread, ThreadStart, ThreadPool, BackgroundWorker, etc), mas a escrita de métodos assíncronos naturalmente foi difícil de fazer e manter.
O recurso pode ser resumido pelo seguinte exemplo: nós mudaremos o método para assíncrono naturalmente apenas alterando o seu tipo de retorno.

public static IEnumerable<int> getPrimes(int min, int count)
{
    return Enumerable.Range(min, count).Where
      (n => Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i =>
        n % i > 0));
}

Dependendo dos parâmetros min e count esse método pode durar um bom tempo. Uma maneira de torna-lo assíncrono é simplesmente trocando o tipo de retorno como no exemplo a seguir:
 
public static Task<IEnumerable<int>> getPrimesAsync(int min, int count)
{
     return Task.Run (()=> Enumerable.Range(min, count).Where
      (n => Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i =>
        n % i > 0)));
}

No exemplo acima, notem que nós mudamos o nome do próprio método adicionando Async como prefixo e essa é a regra que devemos seguir. Como vocês podem ver o retorno é uma Task, anteriormente era void e foi mudado para Task<T> onde T é o tipo de retorno do método.

O que é Task ?

Task é simplesmente uma implementação de  IAsyncResult .
Agora quando um método retorna Task<T> ele fica no estado awaitable isso significa que você pode chama-lo usando a keyword await, e sempre que você usar await o controle da execução voltará imediatamente e não haverá impacto na capacidade de resposta da sua aplicação.

Vamos ver como nós chamamos esses métodos acima:

private static void PrintPrimaryNumbers()
{
    for (int i = 0; i < 10; i++)
        getPrimes(i * 100000 + 1, i * 1000000)
            .ToList().
            ForEach(x => Trace.WriteLine(x));
}

PrintPrimaryNumbers() é um método que podemos chamar diretamente e tradicionalmente, neste exemplo estou chamando o método 10 vezes, ele será chamado consequentemente e nós veremos quanto tempo demora até ele ser finalizado.

private static async void PrintPrimaryNumbersAsync()
{ 
    for (int i = 0; i < 10; i++)
    {
        var result = await getPrimesAsync(i * 100000 + 1, i * 1000000);
        result.ToList().ForEach(x => Trace.WriteLine(x));
    }
}

Enquanto PrintPrimaryNumbersAsync() é decorado pela keyword async ele chama getPrimesAsync()” de forma assíncrona. Uma vez que é chamado, a execução imediatamente retorna para a thread principal e uma vez que qualquer uma das outras threads é finalizada, a thread principal terá o controle de volta (no nosso caso, escrever os números principais que podem ser encontrados no intervalo fornecido).


Agora veremos o código Main:
static void Main(string[] args)
{
 
    DateTime t1 = DateTime.Now;
    PrintPrimaryNumbers();
    var ts1 = DateTime.Now.Subtract(t1);
    Trace.WriteLine("Finished Sync and started Async");
    var t2 = DateTime.Now;
    PrintPrimaryNumbersAsync();
    var ts2 = DateTime.Now.Subtract(t2);
 
    Trace.WriteLine(string.Format(
      "It took {0} for the sync call and {1} for the Async one", ts1, ts2));
 
    Trace.WriteLine("Any Key to terminate!!");
  
}
 
Você pode me dizer a diferença entre ts1 e ts2 ?
Aqui está o resultado :
Finished Sync and started Async
 
Demorou 00:32:16.1627422 para a chamada síncrona e 00:00:00.0050003 para a chamada assíncrona.



Category

Category

  • (1)
  • (1)
  • (1)
  • (1)
  • (1)
  • (1)

Category

Category