Jeff Meatball Yang
Jeff Meatball Yang

Reputation: 39027

Alternative to BackgroundWorker that accepts more than one argument?

The BackgroundWorker object allows us to pass a single argument into the DoWorkEventHandler.

// setup/init:
BackgroundWorker endCallWorker = new BackgroundWorker();
endCallWorker.DoWork += new DoWorkEventHandler(EndCallWorker_DoWork);
...
endCallWorker.RunWorkerAsync(userName);

// the handler:
private void EndCallWorker_DoWork(object sender, DoWorkEventArgs e)
{
    string userName = e.Argument as string;
    ...
}

To pass multiple arguments, I must wrap them in an object, like this poor string array:

// setup/init:

BackgroundWorker startCallWorker = new BackgroundWorker();
startCallWorker.DoWork += new DoWorkEventHandler(StartCallWorker_DoWork);
...
startCallWorker.RunWorkerAsync(new string[]{userName, targetNumber});


// the handler:
private void StartCallWorker_DoWork(object sender, DoWorkEventArgs e)
{
    string[] args = e.Argument as string[];
    string userName = args[0];
    string targetNumber = args[1];
}

Is there another object or pattern that allows us pass multiple arguments nicely, or ideally, write our own signature?

Upvotes: 32

Views: 23405

Answers (7)

Azhar Khorasany
Azhar Khorasany

Reputation: 2709

Create a class that holds all your arguments

Class MyClass
{
     private string m_Username = string.Empty;
     private int m_Targetnumber;

     public MyClass(){}

     public string Username
     {
         get { return m_Username; }
         set { m_Username = value; }
     }

     public int TargetNumber
     {
         get { return m_TargetNumber; }
         set { m_TargetNumber = value; }
     }
 }



// setup/init:

BackgroundWorker startCallWorker = new BackgroundWorker();
startCallWorker.DoWork += new DoWorkEventHandler(StartCallWorker_DoWork);
...

MyClass thisClass = new MyClass();
thisClass.Username = "abcd";
thisClass.TargetNumber = 1234;
startCallWorker.RunWorkerAsync(thisClass);


// the handler:
private void StartCallWorker_DoWork(object sender, DoWorkEventArgs e)
{
     MyClass args = (MyClass)e.Argument;
     string userName = args.Username;
     string targetNumber = args.TargetNumber;
}

Upvotes: 1

Peter Long
Peter Long

Reputation: 4012

instead of a typed object. C# 4.0 provides us with tuple. We could use a tuple to hold multiple args. Then there is no need to declare a new class.

Upvotes: 4

Ben M
Ben M

Reputation: 22492

You could use a closure (Lambda):

backgroundWorker.DoWork += (s, e) => MyWorkMethod(userName, targetNumber);

Or with delegate (anonymous method) syntax:

backgroundWorker.DoWork += 
    delegate(object sender, DoWorkEventArgs e)
    {
        MyWorkMethod(userName, targetNumber);
    };

Upvotes: 45

Vijay Patel
Vijay Patel

Reputation: 17532

What's wrong with using a typed object?

internal class UserArgs
{
    internal string UserName { get; set; }
    internal string TargetNumber { get; set; }
}

var args = new UserArgs() {UserName="Me", TargetNumber="123" };
startCallWorker.RunWorkerAsync(args);

Upvotes: 12

McAden
McAden

Reputation: 13972

Object can be a list or array or some such. Just make your object a container of some sort, then cast within the BackgroundWorker. You need to make sure you're always passing in the same type though.

Upvotes: 3

Sam Harwell
Sam Harwell

Reputation: 99879

Maybe pass a lambda function as your object? Then you'd call it in the DoWork handler.

endCallWorker.RunWorkerAsync(new Action( () => DelegatedCallTarget(userName, targetNumber) ));

Upvotes: 2

Kenan E. K.
Kenan E. K.

Reputation: 14111

Why not have the "one" object passed be an array of parameters? You only need to cast it back to array inside the method from the object parameter.

Upvotes: 0

Related Questions