C# BackgroundWorker not reporting progress in order

Viewed 35

I have two forms, a main form that takes in parameters and a progress bar form that shows the progress of the time-consuming work. A problem I'm having right now is that the BackgroundWorker is not reporting progress in order, which makes the progress bar look weird and not accurate.

I'm new to winforms so I don't know if this has to do with the way how I set up my forms.

The main form has a "Copy" button which starts the process (ProgressBarForm takes in backgroundWorker1 because I have a cancel button on the form):

    private void copyButton_Click(object sender, EventArgs e)
    {
        if (!backgroundWorker1.IsBusy)
        {
            backgroundWorker1.RunWorkerAsync();
            
        }
        progBarForm = new ProgressBarForm(backgroundWorker1);
        progBarForm.ShowDialog();
    }

my DoWork looks like this:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {

        while (progBarForm == null)
        {
            // wait
        }

        if (backgroundWorker1.CancellationPending)
        {
            e.Cancel = true;
        } 
        else
        {
            startCopy(e);
        }

    }

StartCopy (some lines are omitted, but the structure is the same):

        private void startCopy(DoWorkEventArgs e)
    {
        List<string> names = readExcelFile(excelPath);
        // update progress bar max
        progBarObj.max = names.Count();
        progBarObj.action = (int) ProgObjAction.updateMax;
        backgroundWorker1.ReportProgress(0, progBarObj);


        foreach (string name in names)
        {
            if (backgroundWorker1.CancellationPending)
            {
                // if cancel button is clicked, cancel the work
                e.Cancel = true;
                return;
            }

            // update progress bar label
            progBarObj.name = name;
            progBarObj.action = (int)ProgObjAction.updateName;
            backgroundWorker1.ReportProgress(0, progBarObj);

            // where time-consuming work is being done
            copyFile(name, e);

            // perform progress bar step
            progBarObj.action = (int)ProgObjAction.step;
            backgroundWorker1.ReportProgress(0, progBarObj);
        }
    }

ProgBarObj is a struct that stores update info, and ProgObjAction is just an enumeration. copyFile function also calls ReportProgress.

ProgressChanged looks like this:

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        ProgObj progObj = (ProgObj)e.UserState;
        
        switch (progBarObj.action)
        {
            case (int)ProgObjAction.updateName:
                progBarForm.updateLabel(progObj.name);
                break;
            case (int)ProgObjAction.updateMax:
                progBarForm.updateMax(progObj.max);
                break;
            case (int)ProgObjAction.step:
                progBarForm.performStep();
                break;
        }
             
    }

Within the ProgressBarForm I have functions that update the label, progress bar maximum and perform step.

I did some research and found out that BackgroundWorker ProgressChanged won't execute in order if it's a console app, but this is not my case here. ProgressChanged also runs on the main thread. So I really don't understand what's going on.

Any help would be appreciated!

0 Answers
Related