Colaboraciones en el Guille

Ejecución Asíncrona de Comandos

Asynchronous Execution Commands

 

Fecha: 07/Feb/2006 (07/feb/2006)
Autor: Aldo R. Neyra Rocha (e-mail: [email protected])


Introducción

En esta oportunidad quiero comentarles acerca de una de las características de ADO NET 2.0, que es la Ejecución Asíncrona de Comandos (Asynchronous Execution Commands). Esta característica ya era soportada desde la versión 1.x del Framework pero el modelo fue implementado al nivel de código del usuario, es decir uno mismo debía de implementar esta funcionalidad mediante código para poder conectar procedimientos asincronamente a la base de datos y ejecutar comandos.

En esta nueva versión del Framework 2.0 esta características se ha mejorado, permitiendo aumentar la performance de nuestros aplicativos. Pero veamos como funciona esto; cuando nuestro aplicativo interactúa con alguna DBMS (Data Base Managment System) mediante la ejecución de comandos este debe de esperar a que esta acción sea completada para continuar su ejecución ; es decir el control vuelva al aplicativo una vez que el comando se haya completado en la DBMS, de allí que derivamos a que este era un modelo síncrono.

Con las mejoras echas en esta nueva versión y la adición una API asíncrona, podemos tomar ventaja en escenarios donde es necesario continuar con la ejecución del aplicativo mientras se ejecuta algún comando contra una base de datos. Es decir ahora ya tenemos el soporte necesario para no tener que esperar a que la base de datos termine de ejecutar el comando, mientras nosotros realizamos otras acciones en nuestros aplicativos; lo que mejora la performance y que las aplicaciones clientes no sean bloqueadas mientras se ejecutan comandos.

Esta funcionalidad actualmente solo se encuentra soportada para el proveedor SqlClient (proveedor de acceso a datos para SqlServer), pero se espera a la incorporación de los otros tres proveedores de acceso a datos.

Los métodos asíncronos se aplican al objeto Command, utilizando dos partes, un Begin para empezar la ejecución asíncrona y un End para terminar y obtener el valor de retorno de esta manera tenemos:

BeginExecuteReader EndExecuteReader
BeginExecuteNonQuery EndExecuteNonQuery
BeginExecuteXmlReader. EndExecuteXmlReader

Si notamos son muy parecidos a los clásicos métodos síncronos del objeto Command, acá no tenemos el ( Begin/End )ExecuteScalar debido a que este es como un ExecuteReader que te devuelve un valor.

La implementación es sencilla:

IAsyncResult ar = cmd.BeginExecuteReader();

/*Acá realizamos otras operaciones como el llenado de otro datagrid , etc.*/
SqlDataReader reader = cmd.EndExecuteReader(ar);

El tipo IAsyncResult sirve de referencia para funciones de rastreo de la operación.
Debemos tener en cuenta que cuando invocamos al método EndExecute de los readers sin verificar la completación de las operaciones asíncronas estamos obligando a bloquear al método llamante hasta que la operación termina, tal como fuese un operación síncrona envuelta de cierto asincronismo.

Para que todo esto funcione, nuestra cadena de conexión debe de incorporar un keyword extra que es la de : async=true o también : Asynchronous Processing = true. Debemos tener cuidado en no utilizarlo cuando no vamos a ejecutar operaciones asíncronas puesto que destinaríamos recursos del sistema que nunca utilizaremos.

Una de las dificultades que se presentan en este modelo es que no sabemos cuando el otro hilo a terminado de completar su operación para esto tenemos métodos como:

-Callback: Pasa dos parametros al método Begin en una de sus sobrecargas, uno es un delegado y el otro un objeto de estado (state), el cual estará disponible a travez del IAsyncResult pasado como parametro al delegado.

-Synchronization Objects : En este método se hace uso de la propiedad WaitHandle del IAsyncResult el que contiene un objeto event, el cual puede ser utilizado en sincronizaciones como WaitHandle.WaitAny y WaitHandle.WaitAll.

-Pooling: Aca se hace uso de la propiedad IsCompleted del objeto IAsyncResult y mediante esta propiedad iremos verificando cada cierto tiempo si la operación asíncrona fue terminada para finalizar su ejecución.


Espacios de nombres usados en el código de este artículo:

System
System.Data
System.Data.SqlClient


ir al índice principal del Guille