¿Cómo llamar a un método asíncrono desde un captador o definidor?

Resuelto Doguhan Uluca asked hace 13 años • 15 respuestas

¿Cuál sería la forma más elegante de llamar a un método asíncrono desde un captador o definidor en C#?

Aquí hay un pseudocódigo para ayudarme a explicarme.

async Task<IEnumerable> MyAsyncMethod()
{
    return await DoSomethingAsync();
}

public IEnumerable MyList
{
    get
    {
        //call MyAsyncMethod() here
    }
}
Doguhan Uluca avatar Jul 07 '11 03:07 Doguhan Uluca
Aceptado

No existe ninguna razón técnicaasync por la que las propiedades no estén permitidas en C#. Fue una decisión de diseño decidida, porque las "propiedades asincrónicas" son un oxímoron.

Las propiedades deben devolver valores actuales; no deberían iniciar operaciones en segundo plano.

Normalmente, cuando alguien quiere una "propiedad asincrónica", lo que realmente quiere es una de estas:

  1. Un método asincrónico que devuelve un valor. En este caso, cambie la propiedad a un asyncmétodo.
  2. Un valor que se puede utilizar en el enlace de datos pero que se debe calcular/recuperar de forma asincrónica. En este caso, utilice un asyncmétodo de fábrica para el objeto contenedor o utilice un async InitAsync()método. El valor vinculado a datos será default(T)hasta que se calcule/recupere el valor.
  3. Un valor que es costoso de crear, pero que debe almacenarse en caché para uso futuro. En este caso, utilícelo AsyncLazy desde mi blog o biblioteca AsyncEx . Esto le dará una awaitpropiedad capaz.

Actualización: cubro las propiedades asincrónicas en una de mis publicaciones recientes de blog sobre "OOP asíncrona".

Stephen Cleary avatar Dec 06 '2012 01:12 Stephen Cleary

No puede llamarlo de forma asincrónica, ya que no hay soporte para propiedades asincrónicas, solo métodos asincrónicos. Como tal, hay dos opciones, ambas aprovechando el hecho de que los métodos asincrónicos en el CTP son en realidad solo un método que devuelve Task<T>o Task:

// Make the property return a Task<T>
public Task<IEnumerable> MyList
{
    get
    {
         // Just call the method
         return MyAsyncMethod();
    }
}

O:

// Make the property blocking
public IEnumerable MyList
{
    get
    {
         // Block via .Result
         return MyAsyncMethod().Result;
    }
}
Reed Copsey avatar Jul 06 '2011 20:07 Reed Copsey