Saltar al contenido principal

 none
Devolver datos Asincronicamente con BeginExecuteReader y cargar resultados en un datagridview de un windows form. RRS feed

  • Pregunta

  • Hola que tal,

    Una vez más acudo a este foro a ver si alguien puede darme una mano en este tema que me ha hecho perder ya algunas horas y aún no le encuentro respuesta.

    El tema va en las llamadas asincronicas a la base de datos usando los metodos beginXXX (BeginExecuteReader,BeginExecuteNonQuery) y sus respectivos endXXX.

    El planteamiento del problema es el siguiente:  tengo un winform con un datagridview y un boton que realiza una consulta asincronica a la db, el usuario puede seguir haciendo otras tareas y luego cuando finaliza la consulta (supongamos con un tiempo d respuesta d unos 5 segundos como los hacen en la msdn) devolver esos datos a el datagridview.

    Ahora para resolver esto hay varios ejemplos circulando por la web y otros en las msdn de Microsoft, ambos coinciden en que: se debe crear una cadena de conexión con el parametro asynchronous Processing en true, luego si se desea esperar filas se debe usar el BeginExecuteReader. Para obtener los resultados sin crear una especie d congelamiento en la aplicación se puede usar un método de devolución de llamada en este caso un AsyncCallback que ejecuta un procedimiento "X" cuando termine la ejecución asincronica asignada a éste, a su vez a este procedimiento se le pasa un parametro de tipo IAsyncResult que es el que llevará la información y el estado d nuestra llamada asincronica de tal suerte que en el procedimiento llamado al finalizar la tarea ponemos el Endxxx correspondiente (en este caso endExecuteReader) y con otras lineas d código más obtener los resultados de la consulta.

    Ahora bien hasta este punto todo sale bien, pero hay algo q no muestra ninguno d los ejemplo que he visto, y es: ¿Como hacer esto si estas trabajando lo que son datos en una clase aparte ("la tipicia clase de datos") o en capas?. y es que todos los ejemplos implementan esta solución pero haciendo las importaciones y llamando los comandos en el propio formulario de windows.

    Ya en la práctca generalmente uno tiene un formulario de windows con el datagridview y desde este formulario se suele instanciar la clase de datos y llamar al método o procedimiento que haga la llamada asincronica.

    La pregunta es como seria la forma correcta de hacerlo en este escenario??, o realmente es necesario pasar esta parte del código (que podria pertenecer a tu clase de datos) al formulario. Se que para resolver esto también podria utilizar hilos, pero quisiera saber cual es el alcance que puedo tener con estos métodos asincronicos de ado.net.

    por ahora lo he hecho poniendo en mi clase de datos el procedimiento que hace la llamada o la consulta asincronica, pero al setearle al AsyncCallback el procedimiento que debe ejecutar una vez terminada esa consulta no me ha quedado mas que fijarle un procedimiento del formulario donde tengo el datagridview...y no c si esté correcto, de funcionar funciona, pero me gustaria saber cual sería la manera correcta ya q el procedimiento que esta en el formulario obviamente usa controles de datos por lo que he tenido que volver a poner la importación del namespace sqlclient en el formulario.

    Acontinuación muestro el código como quedó más o menos, y con eso me despido esperando que alguien pueda darme alguna orientación sobre el tema.

    Gracias de antemano.

    El código va mas o menos así:

    en la  clase de datos va:

    Sub traer_asincronicamente()
            Dim conn As New SqlConnection("Data Source=SERVER-xxx;Initial Catalog=xxxx;Integrated Security=True;asynchronous Processing=true")

            Dim comando As New SqlCommand("waitfor delay '00:00:08';Select * from destino_marq", conn)
            conn.Open()
            Dim callback As New AsyncCallback(AddressOf frm_llamadas_asincronicas.mensaje)  'aqui es donde no me quedo mas q anclarlo al formulario
            Dim resultados As IAsyncResult = comando.BeginExecuteReader(callback, comando)
        End Sub


    y lo que va en el formulario quedaría:

      Sub mensaje(ByVal resultado As IAsyncResult) 'este es el procedimiento q se ejecuta cuando termina la llamada asincrónica
            Dim comando As SqlCommand = CType(resultado.AsyncState, SqlCommand)
            Dim lector As SqlDataReader = comando.EndExecuteReader(resultado)
            Dim tabla As New DataTable
            tabla.Load(lector)
            lector.Close()
            Invoke(New mydelegado(AddressOf cargar_tabla), tabla)'esto para q me deje acceder al control si problemas
        End Sub


        Delegate Sub mydelegado(ByVal tabla As DataTable)
        Private Sub cargar_tabla(ByVal tabla As DataTable)
            Dgv1.DataSource = tabla
        End Sub
    • Cambiado Enrique M. Montejo lunes, 11 de julio de 2011 17:09 acceso a datos (De:Lenguaje VB.NET)
    miércoles, 7 de julio de 2010 17:21