none
¿Como pasar mas de un parametro a un BackGroundWorker? RRS feed

  • Pregunta

  • Hola, estoy usando un BackGroundWorker para procesar un DataGridView, que es lo que le paso como parámetro en e.Argument

    Ahora necesito agregar dos variables booleanas a los parámetros que le paso, ¿Es eso posible?

    He probado haciendo lo siguiente, lo corrí colocando un breakpoint en el código y parece que funciona.

    Dim Xarray As New List(Of Object) Xarray.Add(Me.DataGridViewHistorico) Xarray.Add(True) Xarray.Add(False)

    BgWInsertarEnBase.RunWorkerAsync(Xarray)


    ¿Esta bien lo que hice? Porque lo saque de la galera y no se si podría tener alguna contra ese código.


    The Real Blue

    martes, 13 de enero de 2015 19:21

Respuestas

Todas las respuestas

  • RunWorkerAsync admite un objeto como parámetro, pero ese objeto puede tener todas las propiedades que te dé la gana. Piensa que en un objeto puedes poner toda la información que quieras. Símplemente declara una clase con las propiedades que quieras, creas un objeto de esa clase y se los pasas a RunWorkerAsync.

    Por ejemplo

    Public Class AsyncOperationData
       Public Property MiPropiedadBooleana As Boolean
       Public Property MiPropiedadEntera As Integer
       Public Property MiColeccionDeLoQueSea As List(Of LoQueSea)
       ' etc etc
    
    End Class

    Creas un objeto de AsyncOperationData, le asignas las propiedades y se lo pasas a RunWorkerAsync.

    Pero ten cuidado, según has dicho uno de los datos es el datagrid. Ten en cuenta que es ilegal acceder a controles windows forms desde un hilo diferente del que lo creo. Así que es ilegal acceder al DataGrid desde el evento BackgroundWorker.DoWork porque el procedimiento de evento de este evento se ejecuta en un hilo diferente.



    Jesús López


    EntityLite a lightweight, database first, micro orm

    martes, 13 de enero de 2015 20:00
  • ¿De la forma que estoy pasando el datagridview mediante el array también es ilegal?

    ¿No hace una copia en memoria del datagridview exclusiva para el BackGroundWorker?

    Gracias por responder, saludos.


    The Real Blue

    martes, 13 de enero de 2015 20:25
  • No, no se hace ninguna copia exclusiva del datagrid para el BackgroundWorker, se pasa una referencia del objeto, no una copia del objeto.

    Así que me temo que vas por mal camino...



    Jesús López


    EntityLite a lightweight, database first, micro orm

    martes, 13 de enero de 2015 20:28
  • ¿Y con la clase que pusiste de ejemplo si se hace una copia exclusiva para el BackGroundWorker?

    The Real Blue

    martes, 13 de enero de 2015 21:00
  • >> ¿Y con la clase que pusiste de ejemplo si se hace una copia exclusiva para el BackGroundWorker? <<

    Pues me temo que tampoco.

    Una posible alternativa sería copiar los datos contenidos en el DataGrid en alguna estructura de datos para pasárselos al BackgroundWorker.

    ¿Pero por qué no nos cuentas qué es lo que quieres hacer en segundo plano? 

    Así, quizá podríamos darte alguna solución.



    Jesús López


    EntityLite a lightweight, database first, micro orm

    martes, 13 de enero de 2015 21:16
  • Donde sí es legal acceder al DataGrid, es en el evento BackgroundWorker.ProgressChanged. Los argumentos de este evento tienen una propiedad UserState que podrías usar para actualizar el datagrid, si es eso lo que necesitas.

    Desde BackgroundWorker.DoWork puedes llamar a BackgroundWorker.ReportProgress pasándole ese UserState que luego se procesa en el evento ProgressChanged.



    Jesús López


    EntityLite a lightweight, database first, micro orm



    martes, 13 de enero de 2015 21:24
  • Lo que hago en segundo plano es insertar los datos que proceso en el datagridview en una tabla, para eso necesito generar querys y todo ese proceso lleva algunos segundos, dependiendo de cuantas lineas sean y que tan ocupado este el motor de la base de datos.

    Por eso uso BackGroundWorker para no colgar la GUI.

    De todos modos estoy viendo que en el DoWork creo una variable nueva y le paso los datos del e.Argument, asi que ahí  es donde, creo, se hace la copia de los datos, por eso es que funciona y no da error.

    Luego en el RunWorkedCompeted paso los datos de e.Result al Datatable ligado al DataGridView


    The Real Blue

    miércoles, 14 de enero de 2015 13:38
  • ¡Que no se hace ninguna copia de los datos! que lo que estás asignando son referencias a objetos. El e.argument es el mismo objeto que le pasaste a RunWorkerAsync.



    Jesús López


    EntityLite a lightweight, database first, micro orm

    miércoles, 14 de enero de 2015 14:51
  • Pero e es ByVal, no ByRef.

    The Real Blue

    miércoles, 14 de enero de 2015 15:11
  • pero e es de tipo referencia no de tipo valor. Cuando pasas por valor un tipo referencia se pasa una copia de la referencia, la cual hace referencia (valga la redundancia) al mismo objeto.

    Me temo que tienes un poco confuso los conceptos de tipo valor, tipo referencia, paso por valor y paso por referencia.



    Jesús López


    EntityLite a lightweight, database first, micro orm

    jueves, 15 de enero de 2015 16:28