2
votes

I create a backgroundworker process in the form..

 BackgroundWorker bw = new BackgroundWorker
        {
            WorkerReportsProgress = true,
            WorkerSupportsCancellation = true
        };  

Also, i have a progress bar control inside the form(progress bar minimum and maximum values are 1 and 100).

In my button click,

where the click event will fire the actual method calls which are supposed to run in the background and in parallel, start showing the progress bar steps....

if (bw.IsBusy)
 {
    return;
 }

 bw.DoWork += (bwSender, bwArg) =>
 {
   MethodCall1(); - Does some database insertions..
   MethodCall2(); - Does some database select...
 }

bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

bw.RunWorkerCompleted += (bwSender, bwArg) =>
{

  bw.Dispose();                  
};

bw.RunWorkerAsync();

For progress bar to show the progressing...

void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
   progressBar.Value = e.ProgressPercentage;
}

The issue i face is, progress bar is not stepping, it stands still and there is no progress bar's progress.

I also tried inserting bw.ReportProgress(integervalue) in my actual methods, but, it didn't help.

How can i have a backgroundworker thread handling method calls and in parallel display the progress of progress bar, after the method calls are done, i want to end the progress bar step.

1
If you set a breakpoint in bw_ProgressChanged is it reached? Does e.ProgressPercentage have a value you would expect? What are the min/max values of progressBar compared to the value in e.ProgressPercentage?Eric J.
Clearly your code is missing the required ReportProgress() calls so that progress bar isn't going to move. It simply isn't always possible to calculate a meaningful progress value, you don't always know enough about what the dbase engine is doing. The only alternative then is to use ProgressBar.Style = Marquee. The "working on it, not dead" option.Hans Passant
If i set style of progress bar to Marquee, i can see the progress bar, however when i change that to Blocks, i don't see the progress of the progress bar.Sharpeye500
You should only wire up the events ONCE, like in the constructor or the Load() event of the Form. Also, if you Dispose() of the BackgroundWorker, how will it run again the next time the button is clicked? In your MethodCall1() and MethodCall2() methods, are you by chance declaring a local BackgroundWorker() called "bw"?Idle_Mind
don't know about BGWorker but usually syntax object.event += () => {} is considered leaky. A good way is to declare variable first: var handler = () => {}. Then object.event += handler; and later object.event -= handler;T.S.

1 Answers

2
votes

As the others stated in the comments, you should move the wiring up of the events to the form constructor or to an initialization method. If you add them to BackgroundWorker on every button click, then the methods will be executed twice on the second click, three times on the third click, etc.

Try putting your ReportProgress calls right after your method calls in your DoWork code. As Hans stated above, unless you have a really good idea of how long your method calls take relative to each other, this will not really be an accurate representation of progress.

As for the Dispose, BackgroundWorker inherits from Component, which implements IDisposable. However, BackgroundWorker doesn't override the base implementation to actually dispose of anything so calling it just removes it from the components collection. It doesn't need to be called explicitly.

Try something like this:

public partial class Form1 : Form
{
    BackgroundWorker bw = new BackgroundWorker
    {
        WorkerReportsProgress = true,
        WorkerSupportsCancellation = true
    };  

    public Form1()
    {
        InitializeComponent();

        bw.DoWork += (bwSender, bwArg) =>
        {
            //MethodCall1(); - Does some database insertions..
            bw.ReportProgress(50);
            //MethodCall2(); - Does some database select...
            bw.ReportProgress(100);
        };

        bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

        bw.RunWorkerCompleted += (bwSender, bwArg) =>
        {

        };
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (bw.IsBusy)
        {
            return;
        }

        bw.RunWorkerAsync();
    }

    void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
    }
}