¿Cómo llamar a un método asíncrono desde un método síncrono?

Dada la particularidad de la ejecución de métodos asíncronos, éstos no pueden ser llamados desde un método síncrono de una forma normal.

C# no nos permite llamar llamar a un método asíncrono sin utilizar await. Y para poder utilizar await, necesitamos que el método llamante sea asíncrono (debe tener el modificador async en su definición).

Pero en algunos casos,es necesario realizar una llamada desde un método síncrono a uno asíncrono. Por ejemplo, dentro de un constructor. Los constructores son métodos que nunca pueden ser asíncronos, por lo que nunca los podremos definir como async, lo que tampoco nos permite hacer llamadas mediante await.

C# posee una clase TaskFactory, que podemos utilizar para crear una clase helper que nos permita realizar este tipo de llamadas:

internal static class AsyncHelper
{
    private static readonly TaskFactory _myTaskFactory = new 
      TaskFactory(CancellationToken.None, 
                  TaskCreationOptions.None, 
                  TaskContinuationOptions.None, 
                  TaskScheduler.Default);

    public static TResult RunSync<TResult>(Func<Task<TResult>> func)
    {
        return AsyncHelper._myTaskFactory
          .StartNew<Task<TResult>>(func)
          .Unwrap<TResult>()
          .GetAwaiter()
          .GetResult();
    }

    public static void RunSync(Func<Task> func)
    {
        AsyncHelper._myTaskFactory
          .StartNew<Task>(func)
          .Unwrap()
          .GetAwaiter()
          .GetResult();
    }
}

Únicamente deberemos utilizar una expresión lambda para realizar la llamada al método asíncrono:

AsyncHelper.RunSync<tipo_datos>(() => miMetodoAsincrono())

 

await. Y para poder utilizar await, necesitamos que el método llamante sea asíncrono (debe tener el modificador async en su definición)." data-share-imageurl="" style="position:fixed;bottom:0px;left:0px;">