Usando await en un metodo NO asincrono

He recibido varias preguntas relacionadas a este tema, especialmente desde que se popularizo el uso de await y async, muchas personas creen que es algun tipo de caracteristica ‘magica’, cuando en realidad es una consecuencia logica de varias caracteristicas introducidas en la version 4.o del .NET Framework, especialmente de la clase Task. Una duda recurrente es: Como usar await con un metodo NO asincrono.

Supongamos que disponemos de un metodo NO asincrono como el siguiente, que realiza un proceso que puede bloquear el hilo de la interface de usuario, en caso de llamarse desde ahi.

        /// <summary>
        /// This is a blocking call
        /// </summary>
        /// <returns></returns>
        private NetworkInterfaceType GetNetworkInterfaceType()
        {
            var interfaceType = NetworkInterface.NetworkInterfaceType;
            return interfaceType;
        }

Puede haber muchas soluciones, pero la mas simple que puedo recomendar, no necesariamente la mejor es usar el siguiente codigo:

    var interfaceType =await Task.Run(()=>{returnGetNetworkInterfaceType(); });

Obviamente el metodo donde se introduzca la anterior linea, necesariamente debe tener la palabra reservada async.

Un saludo.

Descargar una imagen y codificarla en Base64

Durante el Diplomado de Windows Phone 8, hubo la necesidad de descargar un grupo de imagenes desde una URL y guardarlas, inicialmente la idea podia pasar por guardarlas en una BD pero solo con fines de experimentacion decidi guardar las imagenes en un archivo de texto codificada (encoded) en base64.

Aqui les comparto el metodo asyncrono que utilice para tal finalidad:

        public Task<string> DownloadImageAsync(string url)
        {
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
            Task<WebResponse> requestTask = Task.Factory.FromAsync(
                req.BeginGetResponse, result => req.EndGetResponse(result),
                TaskCreationOptions.None);

            Task<string> resultTask = requestTask.ContinueWith(responseTask =>
            {
                using (
                    var stream =
                        responseTask.Result.GetResponseStream())
                {
                    int len = (int)stream.Length;
                    byte[] byt = new Byte[len];
                    stream.Read(byt, 0, len);
                    var b64 = System.Convert.ToBase64String(byt);
                    return b64;
                }
            });
            return resultTask;
        }

Como estuve trabajando intensivamente con MVVM, me vi en la necesidad de usar un Convertidor, que aqui se los paso in-extenso:

    public class ImageBase64Converter : IValueConverter
    {

        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string b64Value = (string)value;
            BitmapImage bi = null;
            if (!String.IsNullOrEmpty(b64Value))
            {
                byte[] imageBytes = System.Convert.FromBase64String(b64Value);
                bi = new BitmapImage();
                bi.SetSource(new MemoryStream(imageBytes));
            }
            return bi;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            BitmapImage bi = (BitmapImage) value;

            using (MemoryStream ms = new MemoryStream())
            {
                WriteableBitmap btmMap = new WriteableBitmap(bi.PixelWidth, bi.PixelHeight);
                // write an image into the stream
                Extensions.SaveJpeg(btmMap, ms, bi.PixelWidth, bi.PixelHeight, 0, 100);

                int len = (int)ms.Length;
                byte[] byt = new Byte[len];
                ms.Read(byt, 0, len);
                var b64 = System.Convert.ToBase64String(byt);
                return b64;
            }
        }
        #endregion
    }

Saludos

Simplificando las cosas con Events, EventHandlers & EventArgs

Los eventos son una parte importante dentro del framework .NET, recuerdese que son la implementacion del patron observador, por cierto la implementacion mas elegante que puede hacerse. Sin embargo cuando usamos eventos necesitamos pasar o mas exactamente, informar con ciertos parametros hacia el manejador de eventos, observece los siguientes trozos de codigo:

Supongamos que tenemos una situacion en la que queremos informar del cambio de nombre, algo simple es el siguiente codigo, con este codigo lo maximo que se puede hacer es saber si se ha cambiado el nombre o no

public event EventHandler NombreCambiado;

public void OnNombreCambiado(EventArgs e)
        {
            EventHandler handler = NombreCambiado;
            if (handler != null) handler(this, e);
        }

Que ocurre si queremos informar cual es el nuevo nombre?, las cosas se empiezan a complicar pues quiza queremos usar el siguiente codigo:

        public event EventHandler<EventArgs> NombreCambiado;

        public void OnNombreCambiado(EventArgs e)
        {
            EventHandler<EventArgs> handler = NombreCambiado;
            if (handler != null) handler(this, e);
        }

Sin embargo EventArgs no soporta el paso de parametros, lo recomendado es crear una clase derivada de EventArgs, en el caso del ejemplo la clase se llama NombreEventArgs, como se muestra en el siguiente codigo:

    public class NombreEventArgs: EventArgs
    {
        public string Nombre { get; set; }
        public NombreEventArgs(string nombre)
        {
            Nombre = nombre;
        }
    }

        public event EventHandler<NombreEventArgs> NombreCambiado;

        public void OnNombreCambiado(string nombre)
        {
            EventHandler<NombreEventArgs> handler = NombreCambiado;
            if (handler != null) handler(this, new NombreEventArgs(nombre));
        }

Aqui surge el punto que cada vez que querramos pasar/devolver un parametro de algun tipo, debemos crear una nueva clase? En un principio puede parecer que si, pero a medida que va creciendo una aplicacion podemos encontrarnos con muchas clases que son innecesarias, entonces cual puede ser la solucion?

Crear una clase generica de EventArgs, el resultado, una clase llamada DataEventArgs<T> que la utilizo practicamente en todo proyecto que tengo:

    public class DataEventArgs<T>: EventArgs
    {
        public T Data { get; set; }

        public DataEventArgs(T data)
        {
            Data = data;
        }
    }

La utilizacion?, utilizando el anterior ejemplo:

        public event EventHandler<DataEventArgs<string>> NombreCambiado;

        public void OnNombreCambiado(string nombre)
        {
            EventHandler<DataEventArgs<string>> handler = NombreCambiado;
            if (handler != null) handler(this, new DataEventArgs<string>(nombre));
        }

Saludos.

Remover HTML tags

A raiz de un requerimiento, en el Diplomado de Windows Phone 8, que nos pedia consumir un servicio, que devolvia HTML y colocar el contenido recuperado del servicio, como texto plano, en la aplicacion Windows Phone, tuve que buscar la mejor manera de eliminar los tags HTML, encontre este excelente articulo, y el codigo que pongo a continuacion:

/// <summary>
    /// Methods to remove HTML from strings.
    /// </summary>
    public static class HtmlRemoval
    {
        /// <summary>
        /// Remove HTML from string with Regex.
        /// </summary>
        public static string StripTagsRegex(string source)
        {
            return Regex.Replace(source, "<.*?>", string.Empty);
        }

        /// <summary>
        /// Compiled regular expression for performance.
        /// </summary>
        static Regex _htmlRegex = new Regex("<.*?>", RegexOptions.Compiled);

        /// <summary>
        /// Remove HTML from string with compiled Regex.
        /// </summary>
        public static string StripTagsRegexCompiled(string source)
        {
            return _htmlRegex.Replace(source, string.Empty);
        }

        /// <summary>
        /// Remove HTML tags from string using char array.
        /// </summary>
        public static string StripTagsCharArray(string source)
        {
            char[] array = new char[source.Length];
            int arrayIndex = 0;
            bool inside = false;

            for (int i = 0; i < source.Length; i++)
            {
                char let = source[i];
                if (let == '<')
                {
                    inside = true;
                    continue;
                }
                if (let == '>')
                {
                    inside = false;
                    continue;
                }
                if (!inside)
                {
                    array[arrayIndex] = let;
                    arrayIndex++;
                }
            }
            return new string(array, 0, arrayIndex);
        }
    }

El detalle no termina en copiar y usar el codigo, sino en la necesidad de usar esta clase en un Portable Library, lo que me hizo caer en cuenta que la opcion de compilar las expresiones regulares no estan soportadas en este tipo de librerias de clase (por eso pueden ver que el enumerador tiene un color un tanto diferente en el codigo anterior)

En fin, el metodo utilizado fue: StripTagsCharArray.

Un saludo.

Json Serializacion/Deserializacion

Durante las ultimas cuatro semans estuve participando del Diplomado de Windows Phone 8 que se organizo desde Mexico, con la indispensable presencia de Rodrigo Diaz Concha. Demas esta decir que estuvo genial, la cantidad de cosas recibidas y es mi intencion devolver a la comunidad algunas cosas aprendidas.

Existen situaciones donde es necesario serializar o deserializar un objeto a JSON. Se que existen librerias que lo hacen mas eficientemente, aqui pueden encontrar una comparativa muy interesante de ellas. Pero mi intencion es mantenerlo simple y no necesariamente eficiente (por ahora)

public class JsonHelper
{
/// <summary>
///
JSON Serialization
/// </summary>
public static string JsonSerializer<T>(T t)
{
string result = string.Empty;
using (MemoryStream stream = new MemoryStream())
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
serializer
.WriteObject(stream, t);
stream
.Position = 0;
using (StreamReader sr = new StreamReader(stream))
{
result
= sr.ReadToEnd();
}
}

return result;
}

/// <summary>
///
JSON Deserialization
/// </summary>
public static T JsonDeserialize<T>(string jsonString)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T obj
= (T)serializer.ReadObject(ms);
return obj;
}
}

Saludos