Question

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

Was it helpful?

Solution

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((int)(100/totalSteps)*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);
}

OTHER TIPS

Modify the WorkReportProgress property of the backgroundworker object to true either in the properties window or in code.

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

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.

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top