Chris
Chris

Reputation: 2501

Basic BackgroundWorker usage with parameters

My process intensive method call that I want to perform in a background thread looks like this:

object.Method(paramObj, paramObj2);

All three of these objects are ones I have created. Now, from the initial examples I have seen, you can pass an object into a backgroundworker's DoWork method. But how should I go about doing this if I need to pass additional parameters to that object, like I'm doing here? I could wrap this in a single object and be done with it, but I thought it would be smart to get someone else's input on this.

Upvotes: 21

Views: 48812

Answers (4)

Henk Holterman
Henk Holterman

Reputation: 273179

You can capture them in a lambda for DoWork:

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

e.Argument (i.e. the state value or object passed to BackgroundWorker.RunWorkerAsync()) could be 1 of the 3, but it is of type System.Object and would require boxing. Passing all of the parameters directly in the lambda gives you full type-safety on all of the parameters without any need for boxing or casting.

Upvotes: 6

mservidio
mservidio

Reputation: 13057

You can pass any object into the object argument of the RunWorkerAsync call, and then retrieve the arguments from within the DoWork event. You can also pass arguments from the DoWork event to the RunWorkerCompleted event using the Result variable in the 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.                        
    }

Upvotes: 56

LazyOfT
LazyOfT

Reputation: 1438

The simplest way that comes to my mind would be creating a class with a property for every object you have, and passing that.

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

then in the DoWork you simply do something like:

MyWorkerContext context = e.Argument as MyWorkerContext;

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

Upvotes: 10

NVade
NVade

Reputation: 278

You can pass an Object into the BackgroundWorker.RunWorkerAsync() method. You should wrap your two paramObjs into one Object (you could use an array, a tuple, or some other composite class that you would write) and pass that as the argument into RunWorkerAsync().

Then, when your DoWork event is raised, you can retrieve this values by looking at the Argument property of the DoWorkEventArgs parameter of the event handler.

For a complete example, check out on MSDN: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker%28v=VS.90%29.aspx

Upvotes: 1

Related Questions