Usando async/await en programas de consola

Hoy intentando preparar algunos ejemplos de entrenamiento me tope con una interesante curiosidad de asyn/await y es que usarlo en un programa de consola, probablemente la solucion que muestre es evidente para los con mas experiencia pero como siempre vale aclararlo, esto lo escribo para los que estamos metiendonos mas con async y await.

La idea es que tengo este bloque de codigo que contiene un metodo asincrono que quiero invocar usando await, pero como saben para usar await el metodo que lo contiene tiene que estar marcado con async, entonces se me ocurrio hacer esto:

   1:  class Program
   2:      {
   3:          static async void Main(string[] args)
   4:          {
   5:              var client = new RestClient("https://qrng.anu.edu.au");
   6:              // client.Authenticator = new HttpBasicAuthenticator(username, password);
   7:   
   8:              var request = new RestRequest("/API/jsonI.php", Method.GET);
   9:              request.AddParameter("length", "1"); 
  10:              request.AddParameter("size", "1"); 
  11:              request.AddParameter("time", "1365981445598"); 
  12:              request.AddParameter("type", "uint8");
  13:             
  14:   
  15:              var rx = await ExecuteTaskAsync(client, request, new CancellationToken());
  16:              Console.WriteLine("Showing content...");
  17:              Console.WriteLine(rx.Content);
  18:   
  19:              Console.ReadKey();
  20:          }
  21:   
  22:          private static async Task<IRestResponse> ExecuteTaskAsync(RestClient _restClient, RestRequest request, CancellationToken cancellationToken)
  23:          {
  24:              var taskCompletionSource = new TaskCompletionSource<IRestResponse>();
  25:   
  26:              var asyncHandle = _restClient.ExecuteAsync(request, r => taskCompletionSource.SetResult(r));
  27:   
  28:              using (cancellationToken.Register(() => asyncHandle.Abort()))
  29:              {
  30:                  return await taskCompletionSource.Task;
  31:              }
  32:          }
  33:      }

Pero al intentar colocar el async en la linea 3 se obtiene un error de compilacion que dice:

“an entry point cannot be marked with the ‘async’ modifier “

Para solucionar esto simplemente cambie el codigo agregando un metodo adicionar que realiza la llamada asincrona, removiendo la palabra reservada async y usando el WaitAll, tal como se muestra a continuacion:

   1:  class Program
   2:      {
   3:          static void Main(string[] args)
   4:          {
   5:              var task = OnlyCaller();
   6:              Task.WaitAll(task);
   7:              Console.ReadKey();
   8:          }
   9:   
  10:          private static async Task OnlyCaller()
  11:          {
  12:              var client = new RestClient("https://qrng.anu.edu.au");
  13:              // client.Authenticator = new HttpBasicAuthenticator(username, password);
  14:   
  15:              var request = new RestRequest("/API/jsonI.php", Method.GET);
  16:              request.AddParameter("length", "1"); 
  17:              request.AddParameter("size", "1"); 
  18:              request.AddParameter("time", "1365981445598"); 
  19:              request.AddParameter("type", "uint8"); 
  20:   
  21:              var rx = await ExecuteTaskAsync(client, request, new CancellationToken());
  22:              Console.WriteLine("Showing content...");
  23:              Console.WriteLine(rx.Content);
  24:          }
  25:   
  26:          private static async Task<IRestResponse> ExecuteTaskAsync(RestClient _restClient, RestRequest request, CancellationToken cancellationToken)
  27:          {
  28:              var taskCompletionSource = new TaskCompletionSource<IRestResponse>();
  29:   
  30:              var asyncHandle = _restClient.ExecuteAsync(request, r => taskCompletionSource.SetResult(r));
  31:   
  32:              using (cancellationToken.Register(() => asyncHandle.Abort()))
  33:              {
  34:                  return await taskCompletionSource.Task;
  35:              }
  36:          }
  37:      }

 

Espero que les sea util,

 

Saludos

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *