Background worker, how to structure commands
If i have a method that does something like this
if (ab)
{
//dostuff
}
else if (b)
{
//dostuff
}
else if (c)
{
//do stuff.
}
And each closes the currently open form, and redisplays a new form with different data. How can i wrap each with a form that displays a loading bar just to let the user no something is loading.开发者_运维技巧
I cant open the loading form in the new thread because the progress bar doesnt progress and it seems silly ot have 3 different background workers with do work methods which al ldo the same thing .
thanks
you can easily pass data into the BackgroundWorker
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = true;
if (ab)
{
//dostuff
bw.RunWorkerAsync("ab"); // Run
}
else if (b)
{
//dostuff
bw.RunWorkerAsync("b"); // Run
}
else if (c)
{
//do stuff.
bw.RunWorkerAsync("c"); // Run
}
and then, have:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
string from = sender as string;
switch case (string)
{
case "ab" :
// process
break;
case "b" :
// process
break;
case "c" :
// process
break;
}
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Add here your progress output
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Add here your completed output
}
Handle the ProgressChanged event
to update the progress bar? This will run the callback on the UI thread.
Since the BackgroundWorker runs the task through the DoWork event
, this can be wired to the same method in all cases (or to an arbitrary method). If closures (read: lambdas/anon functions) are used, the correct binding can be trivially kept about.
BackgroundWorker bw = new BackgroundWorker();
// ... other setup such as a unified ProgressChanged
if (ab) {
var greeting = "Hello";
var name = "Fred";
bw.DoWork += (sender, args) => {
// this can be entirely unique or funnel to something unified.
CallSomeSharedMethods();
// use some bound variables (carefully)
// closures are nifty, but watch mutations and lifetimes
// (I find this generally easier than dealing with the DoWorkArgs data)
Console.WriteLine(greeting + " " + name + "!");
// update some progress
bw.ReportProgress(100);
};
} else {
// likewise for others re-using as much
// (or little) as required
}
Happy coding.
As balexandre already noted you can pass data to the Worker. But this data can also by an Action or Func. So you can pass in any method that should be performed in a background worker. An example can be found in this answer.
But be aware that you could run into Cross-Thread exceptions if you try to set any property of a gui element within the background worker task. To accomplish this BeginInvoke
is your friend which can also be encapsulated in an extension method.
精彩评论