web-dev-qa-db-fra.com

Envoi d'arguments à un travailleur en arrière-plan?

Supposons que je veuille envoyer un paramètre int à un travailleur d'arrière-plan, comment peut-on y parvenir?

private void worker_DoWork(object sender, DoWorkEventArgs e) {

}

Je sais qu'il s'agit de worker.RunWorkerAsync () ;, je ne comprends pas comment définir dans worker_DoWork qu'il doit prendre un paramètre int.

132
sooprise

Vous commencez comme ça:

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

puis

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.
}
219
Henk Holterman

Même s’il s’agit d’une question à laquelle on a déjà répondu, je laisserais une autre option, à savoir que l’OMI est beaucoup plus facile à lire:

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

Et sur la méthode du gestionnaire:

private void WorkerDoWork(int value, string text) {
    ...
}
95
dcarneiro

Vous pouvez passer plusieurs arguments comme celui-ci.

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. 

}
44
Zain Ali

Vous pouvez utiliser la propriété DoWorkEventArgs.Argument.

Un exemple complet (même en utilisant un argument int) peut être trouvé sur le site de Microsoft:

9
Dave Mateer

Découvrez la propriété DoWorkEventArgs.Argument :

...
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;
    }
}
6
Jay Riggs

vous pouvez essayer ceci si vous voulez passer plus d'un type d'arguments, commencez par les ajouter tous à un tableau de type Object et passez cet objet à RunWorkerAsync () en voici un exemple:

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

Maintenant, dans la méthode doWork d'ouvrier d'arrière-plan

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......
        //.....
       }
5
sujay

Vous avez besoin de la méthode RunWorkerAsync (objet) et de la propriété DoWorkEventArgs.Argument .

worker.RunWorkerAsync(5);

private void worker_DoWork(object sender, DoWorkEventArgs e) {
    int argument = (int)e.Argument; //5
}
4
alpha-mouse

Vous devez toujours essayer d'utiliser un objet composite avec des types concrets (à l'aide d'un modèle de conception composite) plutôt qu'une liste de types d'objet. Qui se souviendrait de ce que chaque objet est? Pensez à la maintenance de votre code plus tard ... Essayez plutôt quelque chose comme ceci:

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

Puis:

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

puis:

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;                                 
}
4
Denis