views:

1884

answers:

6

I have a background worker running a long database task. i want to show the progress bar while the task is running. Somehow the background worker won't report the progress of the task.

This is what i have:

BackgroundWorker _bgwLoadClients;

_bgwLoadClients = new BackgroundWorker();
_bgwLoadClients.WorkerReportsProgress = true;
_bgwLoadClients.DoWork += new DoWorkEventHandler(_bgwLoadClients_DoWork);
_bgwLoadClients.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bgwLoadClients_RunWorkerCompleted);
_bgwLoadClients.ProgressChanged += new ProgressChangedEventHandler(_bgwLoadClients_ProgressChanged);
_bgwLoadClients.RunWorkerAsync(parms);

private void _bgwLoadClients_DoWork(object sender, DoWorkEventArgs e)
{
    DataTable dt = getdate();
    e.Result = dt;
}

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

I am doing this in WPF, but i guess it won't make a difference.

Thanks in advance

+2  A: 

just report progress on dowork event

private void _bgwLoadClients_DoWork(object sender, DoWorkEventArgs e) {
    int progresValue0to100 = 75;
    (sender as System.ComponentModel.BackgroundWorker).ReportProgress(progresValue0to100);
    //do your jobs..
}

it works like this

Tolgahan Albayrak
+2  A: 

You have to manualy call ReportProgress() to raise the ProgressChanged event.

Daniel Brückner
+1  A: 

You need to call worker.ReportProgress(percentComplete) in your DoWork method. percentComplete should be computed based on the total work. For example:

for(int i =0; i != 100; i++) {
    // do something
    worker.ReportProgress(i);
}

Sometimes it is difficult to partition a job in several chunks to be possible to report the progress. Unfortunately the BackgroundWorker does not solve this, you have to do it yourself.

Aleris
+7  A: 

You need to break your DoWork method down into reportable progress and then call ReportProgress.

Take for example the following:

private void Something_DoWork(object sender, DoWorkEventArgs e) 
{
    // If possible, establish how much there is to do
    int totalSteps = EstablishWorkload();

    for ( int i=0; i<totalSteps; i++)
    {
        // Do something...

        // Report progress, hint: sender is your worker
        (sender as BackgroundWorker).ReportProgress((totalSteps/100)*i, null);
    }

}

If your work can't be predetermined, try adding your own percentages:

private void Something_DoWork(object sender, DoWorkEventArgs e) 
{
    // some work

    (sender as BackgroundWorker).ReportProgress(25, null);

    // some work

    (sender as BackgroundWorker).ReportProgress(50, null);

    // some work

    (sender as BackgroundWorker).ReportProgress(60, null);

    // some work

    (sender as BackgroundWorker).ReportProgress(99, null);
}
Ray Hayes
+1  A: 

Progress must be sent from within the DoWork event by calling the ReportProgress method on the BackgroundWorker. In your case, you can't report any progress because all of the work is being done outside of the DoWork function. You can only report progress before and after the call to getdate(), but not during the call since the BackgroundWorker thread is busy.

Adam Ruth
A: 

Can I call ReportProgress from a method other than DoWork, that is, a method that DoWork calls? I have DoWork calling a method that uses a callback mechanism that reports its progress. The stack would look like this (reversed). xx_DoWork myMethod callbackMethod

I want callbackMethod to call ReportProgress. Is that allowed if I pass the worker object as a param down to callbackMethod?

Valerie