Reputation: 39027
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
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
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
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
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
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
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
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