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!