web-dev-qa-db-fra.com

Utilisation de base de BackgroundWorker avec des paramètres

Mon appel de méthode intensive de processus que je souhaite effectuer dans un thread d'arrière-plan ressemble à ceci:

object.Method(paramObj, paramObj2);

Ces trois objets sont ceux que j'ai créés. Maintenant, à partir des exemples initiaux que j'ai vus, vous pouvez passer un objet dans la méthode DoWork d'un backgroundworker. Mais comment dois-je procéder si je dois passer des paramètres supplémentaires à cet objet, comme je le fais ici? Je pourrais envelopper cela dans un seul objet et en finir avec lui, mais j'ai pensé qu'il serait judicieux d'obtenir la contribution de quelqu'un d'autre à ce sujet.

20
Chris

Vous pouvez passer n'importe quel objet dans l'argument objet de l'appel RunWorkerAsync, puis récupérer les arguments à partir de l'événement DoWork. Vous pouvez également passer des arguments de l'événement DoWork à l'événement RunWorkerCompleted à l'aide de la variable Result dans 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.                        
    }
54
mservidio

Le moyen le plus simple qui me vient à l'esprit serait de créer une classe avec une propriété pour chaque objet que vous avez, et de la transmettre.

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

puis dans le DoWork, vous faites simplement quelque chose comme:

MyWorkerContext context = e.Argument as MyWorkerContext;

context.Worker.Method(context.Parameter1, context.Parameter2);
10
LazyOfT

Vous pouvez les capturer dans un lambda pour DoWork:

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

e.Argument (C'est-à-dire que la valeur d'état ou l'objet passé à BackgroundWorker.RunWorkerAsync()) pourrait être 1 des 3, mais il est de type System.Object Et nécessiterait une boxe. Passer tous les paramètres directement dans le lambda vous donne une sécurité de type totale sur tous les paramètres sans avoir besoin de boxe ou de lancer.

6
Henk Holterman

Vous pouvez passer un objet dans la méthode BackgroundWorker.RunWorkerAsync (). Vous devez envelopper vos deux paramObjs dans un objet (vous pouvez utiliser un tableau, un Tuple ou une autre classe composite que vous écririez) et le passer comme argument dans RunWorkerAsync ().

Ensuite, lorsque votre événement DoWork est déclenché, vous pouvez récupérer ces valeurs en examinant la propriété Argument du paramètre DoWorkEventArgs du gestionnaire d'événements.

Pour un exemple complet, consultez MSDN: http://msdn.Microsoft.com/en-us/library/system.componentmodel.backgroundworker%28v=VS.90%29.aspx

1
NVade