开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜