2011-01-26 14 views
115

Digamos que quiero enviar un parámetro int a un trabajador de fondo, ¿cómo se puede lograr esto?¿Enviando argumentos al trabajador de fondo?

private void worker_DoWork(object sender, DoWorkEventArgs e) { 

} 

sé cuando esto es worker.RunWorkerAsync() ;, no entiendo cómo definir en worker_DoWork que debe tomar un parámetro int.

Respuesta

192

Se empieza así:

int value = 123; 
bgw1.RunWorkerAsync(value); // argument: value, the int will be boxed 

y luego

private void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    int value = (int) e.Argument; // the 'argument' parameter resurfaces here 

    ... 

    // and to transport a result back to the main thread 
    double result = 0.1 * value; 
    e.Result = result; 
} 


// the Completed handler should follow this pattern 
// for Error and (optionally) Cancellation handling 
private void worker_Completed(object sender, RunWorkerCompletedEventArgs e) 
{ 
    // check error, check cancel, then use result 
    if (e.Error != null) 
    { 
    // handle the error 
    } 
    else if (e.Cancelled) 
    { 
    // handle cancellation 
    } 
    else 
    {   
     double result = (double) e.Result; 
     // use it on the UI thread 
    } 
    // general cleanup code, runs when there was an error or not. 
} 
+27

¿Cómo puedo hacer dos argumentos ? – sooprise

+3

¿O envío un objeto lleno de más de un argumento? – sooprise

+19

@soo: utilice una clase auxiliar o un 'Tuple ' (C# 4 +) (Editar: Sí, use un objeto para empaquetarlo todo. Consulte, por ejemplo, DoWorkEventArgs). –

5

Mira la DoWorkEventArgs.Argument Property:

... 
backgroundWorker1.RunWorkerAsync(yourInt); 
... 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // Do not access the form's BackgroundWorker reference directly. 
    // Instead, use the reference provided by the sender parameter. 
    BackgroundWorker bw = sender as BackgroundWorker; 

    // Extract the argument. 
    int arg = (int)e.Argument; 

    // Start the time-consuming operation. 
    e.Result = TimeConsumingOperation(bw, arg); 

    // If the operation was canceled by the user, 
    // set the DoWorkEventArgs.Cancel property to true. 
    if (bw.CancellationPending) 
    { 
     e.Cancel = true; 
    } 
} 
83

A pesar de que esta es una pregunta ya contestada, que dejaría otra opción que la OMI es mucho más fácil de leer:

BackgroundWorker worker = new BackgroundWorker(); 
worker.DoWork += (obj, e) => WorkerDoWork(value, text); 
worker.RunWorkerAsync(); 

Y en el método de controlador :

private void WorkerDoWork(int value, string text) { 
    ... 
} 
+8

No sabía lo que significaba IMO, pensé que era algo de C#. Busqué en Google "C# IMO" y llegué aquí y obtuve la respuesta ... ja ja https://www.quantnet.com/threads/c-c- va-o-java.11433/ – electricalbah

+0

¿Qué hay de 3 parámetros? – YukiSakura

+0

No juego con .NET desde 2012, pero si no me equivoco, puede agregar los parámetros que desee '... => WorkerDoWork (a, b, c);' siempre que coincida con la firma del método '... WorkerDoWork (int a, string b, string c) {...' – dcarneiro

36

Puede pasar varios argumentos como este.

List<object> arguments = new List<object>(); 
        arguments.Add(argument 1); 
        arguments.Add(argument 1); 
        arguments.Add(argument n); 


        backgroundWorker2.RunWorkerAsync(arguments); 

private void worker_DoWork(object sender, DoWorkEventArgs e) { 

    List<object> genericlist = e.Argument as List<object>; 
    extract your multiple arguments from this list and cast them and use them. 

} 
+1

cómo extraer múltiples argumentos del código anterior, por favor ayuda .. – missReclusive

+0

@missReclusive lanzar la" lista genérica " elementos, es decir, supongamos que "argumento 1" es de tipo int y luego int argumento1 = (int) genericlist [0] –

+1

esta es una mala idea en términos de mantenimiento. Debe usar tipos concretos en la Lista porque al menos podrá averiguar lo que estaba haciendo (vea un ejemplo en mi respuesta a continuación) – Denis

4

puede probar esto si desea pasar más de un tipo de argumentos, primero añadirlos a una matriz de tipo de objeto y pasar ese objeto para RunWorkerAsync() Este es un ejemplo:

some_Method(){ 
    List<string> excludeList = new List<string>(); // list of strings 
    string newPath ="some path"; // normal string 
    Object[] args = {newPath,excludeList }; 
      backgroundAnalyzer.RunWorkerAsync(args); 
     } 

Ahora en el método DoWork del trabajador de fondo

backgroundAnalyzer_DoWork(object sender, DoWorkEventArgs e) 
     { 
     backgroundAnalyzer.ReportProgress(50); 
     Object[] arg = e.Argument as Object[]; 
     string path= (string)arg[0]; 
     List<string> lst = (List<string>) arg[1]; 
     ....... 
     // do something...... 
     //..... 
     } 
+0

+1. Enviar los argumentos de esta manera también evita tener que iniciar un New Backgroundworker cada ejecución para evitar repeticiones. (al menos en mi aplicación). Ver mi comentario a continuación relacionado con este problema. También http://stackoverflow.com/a/12231431/503621 y http://stackoverflow.com/questions/12507602/c-sharp-backgroundworker-keep-on-running-dowork – bshea

4

siempre debe tratar de utilizar un objeto compuesto con tipos concretos (utilizando el patrón de diseño compuesto) en lugar de una lista de objetos t ypes. ¿Quién recordaría qué diablos es cada uno de esos objetos? Piense en el mantenimiento de su código más adelante ... En su lugar, intente algo como esto:

Public (Class or Structure) MyPerson 
       public string FirstName { get; set; } 
       public string LastName { get; set; } 
       public string Address { get; set; } 
       public int ZipCode { get; set; } 
End Class 

Y luego:

Dim person as new MyPerson With { .FirstName = “Joe”, 
            .LastName = "Smith”, 
            ... 
           } 
backgroundWorker1.RunWorkerAsync(person) 

y luego:

private void backgroundWorker1_DoWork (object sender, DoWorkEventArgs e) 
{ 
     MyPerson person = e.Argument as MyPerson 
     string firstname = person.FirstName; 
     string lastname = person.LastName; 
     int zipcode = person.ZipCode;         
} 
Cuestiones relacionadas