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 backgroundw开发者_如何学Pythonorker'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.
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.
}
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);
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.
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
精彩评论