Async-Await en Getter y Setter

Hace pocos días recibí esta pregunta en mi facebook por parte de un colega… ¿cómo le hago para consumir un método async Task<foo> desde el getter de una de mis propiedades?

Es decir algo de la forma:

        private string _prop;

        public string Prop
        {
            get
            {
                if (_prop == null)
                    _prop = CrearProp();
                return _prop;
            }
            set { _prop = value; }
        }

        private async Task<string> CrearProp()
        {
            var result = await DoWork();
            return result;
        } 

La primera solución que se viene a la mente es acudir a la propiedad Result de mi Task… pero esto supondría una espera bloqueante y el resultado no siempre puede ser el deseado, no hay como delegar este trabajo al Async/await, claro, siempre que puedas ;).


        public string Prop
        {
            get
            {
                if (_prop == null)
                    _prop = CrearProp().Result;
                return _prop;
            }
            set { _prop = value; }
        } 

Entonces la solución que encontré y le propuse a mi colega, la aprendí de cuando programaba en java, y es crear un método para realizar un Setter, este será void y async, con esto garantizo que se va a poder comunicar con un método asíncrono pero que no será awaitable, el código queda de la forma:

        private string _prop;

        public string Prop
        {
            get
            {
                if (_prop == null)
                    SetProp();
                return _prop;
            }
            set { _prop = value; }
        }

        private async void SetProp()
        {
            Prop = await CrearProp();
        }

        private async Task<string> CrearProp()
        {
            var result = await DoWork();
            return result;
        } 

Cualquier opinión o sugerencia será bien recibida, no dudes en comentar.

Hasta el próximo post

Anuncios
Async-Await en Getter y Setter

5 comentarios en “Async-Await en Getter y Setter

  1. Personalmente en estos casos yo eliminaria el Setter y dejaria como público el método SetProp().
    La sintaxis de propiedad debería usarse tan solo para encapsular cambios de estado. Cosas más complejas (y que potencialmente pueden tardar mucho o dado el caso requerir llamadas asíncronas) deberían dejarse como métodos. Precisamente esa es la diferencia entre un Setter y un método SetXXX. El primero indica que es algo “muy poco costoso” y debería ser potencialmente poco peligroso (aunque este segundo punto es más discutible). El segundo, el método, me indica que puede estar haciendo algo complejo, que puede ser duradero y/o peligroso.

    Al margen de esto, buen post.

    1. Hola Edu! Gracias por comentar.

      Pues si que es cierto esto que dices, por ahí se ven muchas propiedades que hacen mas de lo que deben… pero esto lo veo más como a nivel sintáctico, a que me refiero, si me paso a ver el IL generado por una propiedad XXX, en el IL se ven dos métodos de la forma: get_XXX : Tipo() y set_XXX : void (tipo). Pero si lo miras bien, quitarlo no es una muy buena opción, o como lo veo, si mi setter en este caso permitiera que se le pasara un valor como parámetro hasta si, pero lo empleo es para generar un valor a partir de una operación demorada… no se si me explico bien :-S

      Saludos 😉

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s