Los lanzadores y selectores de Windows Phone son unas herramientas sumamente útiles para poder trabajar cont areas complejas que el sistema operativo puede manejar de una manera sumamente sencilla. Para tomar un ejemplo puedes ver el artículo del lanzador MapsDirectionsTask en este enlace. El objetivo de este post es mezclar esta gran funcionalidad con la más reluciente característica de C#, me refiero a los operadores async/await.
¿Qué es async/await?
Es la nueva propuesta por parte de C# 5.0 para trabajar de manera completamente asíncrona y que puedas evitar el sobresaturamiento (no se si exista esa palabra pero pues ya la usé ) de operaciones en el hilo de la interfaz. Con esta nueva versión colocada en el Framework 4.5 y llevada tanto a WinRT como a Windows Phone, nosotros podremos realizar ciertas tareas de manera asíncrona. Como lo puedes ver en la siguiente imagen.
Trabajar con hilos no había sido tan fácil antes y ahora es muy cómodo poder hacerlo para tareas que exijan muchos recursos.
Después de ver la superficie de esto, vayamos al ejemplo.
PhotoChooserTask
Este selector se encarga de poder trabajar con la galería de imágenes de tu dispositivo. La sintaxis para usarlo de manera ordinaria es la siguiente.
private void btnNormal_Tap(object sender, System.Windows.Input.GestureEventArgs e) { PhotoChooserTask tareaFotografia = new PhotoChooserTask(); tareaFotografia.Completed += (s, a) => { if (a.TaskResult == TaskResult.OK) { BitmapImage datosImagenRecibida = new BitmapImage(); datosImagenRecibida.SetSource(a.ChosenPhoto); imgElegida.Source = datosImagenRecibida; } }; tareaFotografia.Show(); } |
La sintaxis para poder hacerlo de manera asíncrona es la siguiente.
private async void btnAsincrono_Tap(object sender, System.Windows.Input.GestureEventArgs e) { var resultadoFoto = await new PhotoChooserTask().ShowAsync(); if (resultadoFoto.TaskResult == TaskResult.OK) { var datosImagenRecibida = new BitmapImage(); datosImagenRecibida.SetSource(resultadoFoto.ChosenPhoto); imgElegida.Source = datosImagenRecibida; } } |
Considera que en el primer caso estoy utilizando una expresión lambda por simples fines de compactar el código, si lo haces con un manejador de eventos el resultado es más extenso. Por otra parte, en el segundo caso es necesario recurrir a un método extendido llamado ShowAsync(). Puedes leer un poco más acerca de métodos extendidos aquí. La sintaxis del método extendido es la siguiente.
public static Task<TTaskEventArgs> ShowAsync<TTaskEventArgs>(this ChooserBase<TTaskEventArgs> selector) where TTaskEventArgs : TaskEventArgs { var tareaCompletada = new TaskCompletionSource<TTaskEventArgs>(); EventHandler<TTaskEventArgs> completedo = null; completedo = (s, e) =>; { selector.Completed -= completedo; tareaCompletada.SetResult(e); }; selector.Completed += completedo; selector.Show(); return tareaCompletada.Task; } |
La parte fundamental de los métodos extendidos asíncronos es regresar un objeto de tipo Task que es la tarea que se desarrollará en segundo plano. Quizá en este ejemplo no se note una gran diferencia en cuanto al control de recursos pero si notarás lo práctico que puede ser trabajar con elementos asíncronos.
El código e idea original de este artículo es propiedad de Pedro Lamas.
Puedes descargar el ejercicio de ejemplo Puedes descargar el ejercicio de ejemplo aquí.
Muchas gracias Amin, de verdad que me ayudo mucho, más de estos post’s 😀
No sabía que poner después del async, y gracias a ti, supe como hacer que funcionara mi código 😀
public async Task<MobileServiceCollection> consultaHistorial(string ejercicio)
{
try
{
items = await itemDatos
.Where(todoItem => (todoItem.userID == App.MobileService.CurrentUser.UserId && todoItem.ejercicio == ejercicio))
.ToCollectionAsync();
}
catch (MobileServiceInvalidOperationException e)
{
MessageBox.Show(e.Message, «Error loading items», MessageBoxButton.OK);
}
return items;
}