2011-04-26 58 views
19

Mi proceso de llamadas a métodos intensivos que desea llevar a cabo en un subproceso en segundo plano se ve así:Uso básico BackgroundWorker con parámetros

object.Method(paramObj, paramObj2); 

Los tres de estos objetos son los que he creado. Ahora, de los ejemplos iniciales que he visto, puedes pasar un objeto al método DoWork de un trabajador de fondo. ¿Pero cómo debo hacer esto si necesito pasar parámetros adicionales a ese objeto, como lo hago aquí? Podría envolver esto en un solo objeto y terminarlo, pero pensé que sería inteligente obtener la opinión de alguien más sobre esto.

Respuesta

1

Puede pasar un objeto al método BackgroundWorker.RunWorkerAsync(). Debería envolver sus dos paramObjs en un Objeto (podría usar una matriz, una tupla o alguna otra clase compuesta que escribiría) y pasar eso como argumento en RunWorkerAsync().

Luego, cuando se genera su evento DoWork, puede recuperar estos valores mirando la propiedad Argument del parámetro DoWorkEventArgs del controlador de eventos.

Para un ejemplo completo, echa un vistazo en MSDN: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker%28v=VS.90%29.aspx

10

La forma más sencilla que viene a la mente sería la creación de una clase con una propiedad para cada objeto que tiene, y que pasa.

public class MyWorkerContext 
{ 
    public Object1 Worker; 
    public Object2 Parameter1; 
    public Object2 Parameter2; 
} 

luego en la DoWork sólo tiene que hacer algo como:

MyWorkerContext context = e.Argument as MyWorkerContext; 

context.Worker.Method(context.Parameter1, context.Parameter2); 
50

Puede pasar cualquier objeto en el argumento objeto de la llamada RunWorkerAsync, y luego recuperar los argumentos desde dentro del evento DoWork. También puede pasar argumentos del evento DoWork al evento RunWorkerCompleted utilizando la variable Result en DoWorkEventArgs.

public Form1() 
    { 
     InitializeComponent(); 

     BackgroundWorker worker = new BackgroundWorker(); 
     worker.DoWork += new DoWorkEventHandler(worker_DoWork); 
     worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); 

     object paramObj = 1; 
     object paramObj2 = 2; 

     // The parameters you want to pass to the do work event of the background worker. 
     object[] parameters = new object [] { paramObj, paramObj2 }; 

     // This runs the event on new background worker thread. 
     worker.RunWorkerAsync(parameters); 
    } 

    private void worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     object[] parameters = e.Argument as object[]; 

     // do something. 

     e.Result = true; 
    } 

    private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     object result = e.Result; 

     // Handle what to do when complete.       
    } 
+0

Gracias, esto se ve genial! ¿Hay alguna forma de pasar referencias con 'DoWorkEventArgs'? – Agent007

6

Puede capturar en un lambda para DoWork:

bgw.DoWork += (sender, e) => object.Method(paramObj, paramObj2) ; 

e.Argument (es decir, el valor de estado o objeto pasado a BackgroundWorker.RunWorkerAsync()) podría ser 1 de la 3, pero es de tipo System.Object y requeriría el boxeo. Pasar todos los parámetros directamente en el lambda le brinda seguridad de tipo completa en todos los parámetros sin necesidad de boxeo o lanzamiento.

+0

Bien, entonces, ¿qué aspecto tiene esto en el método DoWork? – Chris

+0

Chris, la parte posterior al método '+ =' _is_ the DoWork. –

+0

Me di cuenta. ¿Qué pasa a RunWorkerAsync aquí? – Chris