En la versión 1.x de .NET, cuando generábamos un proxy para acceder al uso de un servicio Web, para cada método disponible en el servicio se generaban una pareja de métodos para lamadas asíncronas. Estos métodos se llamaban igual que el método original pero su nombre comenzaba por Begin y End respectivamente. Por ejemplo, si teníamos un método llamago GetClientes, se generaban los métodos BeginGetClientes y EndGetClientes. Con ellos se podían realizar llamadas asíncronas al método siguiendo una mecánica coherente con la que existe en el resto de la plataforma.
Sin embargo en la versión 2.0, el generador de proxies a servicios Web utiliza una estrategia diferente. Los métodos Begin y End ya no aparecen y a más de uno le puede despistar esto.
Lo cierto es que en esta nueva versión es mucho más sencillo hacer estas llamadas asíncronas ya que no dependemos de IAsyncResult y otras interfaces esotéricas, sino que es tan fácil como declarar un evento para responder a las llamadas. Veamos un ejemplo.
Supongamos que tenemos un método en nuestro servicio Web que se llama GetClientes. En el lado del cliente, tras agregar la referencia Web se genera un proxy en el cual se define un método homónimo. En la versión 2.0 se genera también un método del mismo nombre pero seguido del sufijo "Async", es decir, en nuestro ejemplo sería GetClientesAsync.
Este método es exactamente igual al original pero con la diferencia de que no devuelve un valor y además se devuelve el control inmediatamente al código llamante, ya que se ejecuta en segundaplano de manera asíncrona.
Hasta aquí todo perfecto. La cuestión es que además de hacer la llamada asíncronamente hay que obtener el resultado de dicha llamada. La solución la tenemos fácil ya que también se define un nuevo evento en el proxy que sirve para este propósito. Su nombre es igual al del método pero terminado en "Completed", es decir, GetClientesCompleted en nuestro caso. Este evento necesita un delegado a un método que será llamado automáticamente cuando termine la ejecución asíncrona del método. El gestor del evento no devuelve valor alguno y toma como parámetros un objeto (como casi todos los eventos en .NET) y un objeto de la clase GetClientesCompletedEventArgs, es decir el nombre del metodo seguido de "CompletedEventArgs".
Este objeto tiene una propiedad Result en la que aparecerá el resultado de la llamada. Lo interesante del caso es que, además, no se ha utilizado un tipo Object neutro para Result sino que la propiedad ya será directamente del tipo adecuado. La verdad es que más cómodo posible.
Pongámoslo en la práctica con el ejemplo dado y suponiendo que GetClientes toma como parámetro el nombre del país de origen de los clientes de nuestro interés y devuelve un DataSet genérico con una tabla que contiene los datos de dichos clientes.
Lo primero es definir el manejador de evento de terminación de la llamada, así:
private void GetClientesTerminado(object sender, GetClientesCompletedEventArgs args)
{
DataSet ds = args.Result;
//Se enlaza a un dataGrid, por ejemplo.
this.dataGridView1.DataSource = ds.Tables["Clientes"];
}
Nótese que el resultado es directamente un DataSet. No necesitamos hacer una conversión explícita desde un objeto ni nada similar. Más cómodo imposible.
Ahora sólo falta asignar el manejador del evento y llamar asíncronamente al método correspondiente:
MiServicioProxy proxy = new MiServicioProxy();
proxy.GetClientesCompleted += this.GetClientesTerminado;
proxy.GetClientesAsync("ES");
Como se observa hemos creado una instancia del proxy, asignado en ésta el manejador del evento y luego hemos llamado al método asíncronamente pasándole los parámetros de la manera habitual. Fácil ¿verdad?
Pues eso que hemos ganado ;-)
NOTA: Todo esto y mucho más se explica en el curso sobre servicios Web de campusMVP.com. ¡Apúntante! Aún estás a tiempo de obtenerlo con subvención si eres español y trabajador en activo.