C# - Obtendo um valor de retorno a partir de um Task


Hoje veremos como obter um valor de retorno a partir de uma tarefa ou Task na linguagem C#.

A programação assíncrona é uma forma de programação usada para evitar o bloqueio da thread principal evitando o congelamento da aplicação que esta em atendimento. Na linguagem C# a programação assíncrona é feita usando async e await.


Com métodos assíncronos que possuem um tipo de retorno Task podemos usar o operador await para pausar a execução da thread atual até que o método assíncrono chamado tenha sido concluído.
 

Uma tarefa ou Task é basicamente uma 'promessa' de que a operação a ser realizada não vai ser necessariamente concluída de forma imediata, e, a diferença básica entre Task e Task<t> é que Task é usado em um método assíncrono que não retornar valor enquanto que Task<T> é usado em um método assíncrono que retorna um valor (geralmente do tipo T).

Mas pode acontecer  que você queira obter um valor de retorno de uma tarefa Task, em vez de deixá-la ser executada em segundo plano e aguardar pelo resultado.

Para isso você precisará especificar o tipo de retorno como um parâmetro de tipo para o objeto Task ou seja vai ter usar uma Task<T>.

Para obter o resultado da Task podemos usar:

1- Task.FromResult

Cria um Task<T> que é concluído com êxito com o resultado especificado.

using System;
using System.Threading.Tasks;
namespace CShp_Async1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            int resultado = await Task.FromResult<int>(GetSoma(40, 50));
            Console.WriteLine(resultado);
            Console.ReadKey();
        }
        private static int GetSoma(int a, int b)
        {
            return a + b;
        }
    }
}

2- Task.Run

Coloca o trabalho especificado na fila para execução no ThreadPool e retorna uma tarefa ou um identificador Task<T> para esse trabalho. (É uma forma abreviada de Task.Factory.StartNew)

using System;
using System.Threading.Tasks;
namespace CShp_Async1
{
    class Program
    {
        static async Task Main(string[] args)
        {
             Func<int> function = new Func<int>(() => GetSoma(40, 50));
             int resultado = await Task.Run<int>(function);

            Console.WriteLine(resultado);
            Console.ReadKey();
        }
        private static int GetSoma(int a, int b)
        {
            return a + b;
        }
    }
}

3- Task.Factory.StartNew

É equivalente a Task.Run sendo usado para iniciar uma tarefa.

using System;
using System.Threading.Tasks;
namespace CShp_Async1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Func<int> function = new Func<int>(() => GetSoma(40, 50));
            int resultado = await Task.Factory.StartNew<int>(function);

            Console.WriteLine(resultado);
            Console.ReadKey();
        }
        private static int GetSoma(int a, int b)
        {
            return a + b;
        }
    }
}

E estamos conversados...

"Quem, pois, tiver bens do mundo, e, vendo o seu irmão necessitado, lhe cerrar as suas entranhas, como estará nele o amor de Deus? Meus filhinhos, não amemos de palavra, nem de língua, mas por obra e em verdade."
1 João 3:17,18

Referências:


José Carlos Macoratti