尽管 DoWork 循环是 运行,但 Backgroundworker 没有更新 ProgressBar

Backgroundworker not updating ProgressBar although the DoWork loop is running

我的程序应该允许用户 select 多个文本文件,将内容编译成一个文本文件,然后将其导出到 Excel 文件中。我试过使用进度条,但它只在主循环完成后才更新,而不是在主循环期间更新。一旦循环完成,进度条会立即从最小值跳到最大值。它并没有像它想象的那样缓慢增加。这是我的代码:

public partial class Form1 : Form
{
    List<string> path = new List<string>();
    Workbook excelworkbook = new Workbook();
    Worksheet excelworksheet = new Worksheet("First sheet");
    public Form1()
    {
        InitializeComponent();
    }

    private void addfiles_Click(object sender, EventArgs e)
    {
        DialogResult dr = this.selectFiles.ShowDialog();
        path.Clear();
        if (dr == System.Windows.Forms.DialogResult.OK)
        {
            // Read the files
            foreach (String file in selectFiles.FileNames)
            {
                try
                {
                    path.Add(file);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
            numFiles.Text = path.Count.ToString();
        }
    }

    private void export_Click(object sender, EventArgs e)
    {
        export.Text = "Exporting...";
        export.Enabled = false;
        addfiles.Enabled = false;
        backgroundWorker1.RunWorkerAsync();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            backgroundWorker1.ReportProgress(15);   //15% on progress bar
            string[] readText = File.ReadAllLines(path[0]);
            string[] readText_secondary;
            string filename;
            int real_length = readText.Length - 3;  //create a text file that stores contents temporarily from multiple textfiles first..later will export into an excel file
            using (StreamWriter streamWriter = new StreamWriter(string.Concat(Directory.GetCurrentDirectory(), "\Temp_textfile.txt"), false)) //create temp text file

            {
                for (int i = 12; i <= real_length; i++)
                {
                    backgroundWorker1.ReportProgress(((i / real_length) * 75) + 15);    //suppose to update the UI here
                    streamWriter.Write(string.Concat(readText[i].Substring(4, 42)));    //initial columns
                    streamWriter.Write(string.Concat(readText[i].Substring(59, 13)));    //upperlimit column
                    if (i != 12)
                    {
                        streamWriter.Write(string.Concat(readText[i].Substring(46, 13)));   //results column
                    }
                    else if (i == 12)
                    {
                        filename = Path.GetFileNameWithoutExtension(path[0]);   //serial number column
                        streamWriter.Write(string.Concat(filename + " "));
                    }
                    for (int x = 1; x < path.Count; x++)
                    {
                        readText_secondary = File.ReadAllLines(path[x]);    //secondary files
                        if (x != (path.Count - 1))
                        {
                            if (i != 12)
                            {
                                streamWriter.Write(string.Concat(readText_secondary[i].Substring(46, 13))); //write results
                            }
                            else if (i == 12)
                            {
                                filename = Path.GetFileNameWithoutExtension(path[x]);   //write serial number header
                                streamWriter.Write(string.Concat(filename + " "));
                            }
                        }
                        else
                        {
                            if (i != 12)
                            {
                                streamWriter.WriteLine(string.Concat(readText_secondary[i].Substring(46, 13))); //write results for last column
                            }
                            else if (i == 12)
                            {
                                filename = Path.GetFileNameWithoutExtension(path[x]);   //write serial number header for last column
                                streamWriter.WriteLine(string.Concat(filename + " "));
                            }
                        }
                    }
                }
            }
            var lines = File.ReadAllLines(string.Concat(Directory.GetCurrentDirectory(), "\Temp_textfile.txt"));
            var rowcounter = 0;
            foreach (var line in lines)
            {
                var columncounter = 0;
                backgroundWorker1.ReportProgress(90);
                string[] values = new string[200];  //extract the initial columns
                values[0] = line.Substring(0, 10); values[1] = line.Substring(11, 8); values[2] = line.Substring(20, 8); values[3] = line.Substring(29, 12); values[4] = line.Substring(42, 12);
                for (int y = 0; y < path.Count; y++)
                {
                    values[5 + y] = line.Substring((55 + (13 * y)), 13);    //extract results column
                }
                foreach (var value in values)
                {
                    excelworksheet.Cells[rowcounter, columncounter] = new Cell(value);  //write column by column
                    columncounter++;
                }
                rowcounter++;
            }
            excelworkbook.Worksheets.Add(excelworksheet);   //create the excel file from object
            string timedate = DateTime.Now.ToString("dd-MM-yyyy");
            string excel_name = "\ExportedData_" + timedate;
            int counter = 1;
            string new_path = string.Concat(Directory.GetCurrentDirectory() + excel_name + ".xls"); //this part is to prevent overwriting
            while (File.Exists(new_path))
            {
                new_path = string.Concat(Directory.GetCurrentDirectory() + excel_name + "(" + counter + ")" + ".xls");
                counter++;
            }
            excelworkbook.Save(new_path);   //save into path

            if (File.Exists(string.Concat(Directory.GetCurrentDirectory(), "\Temp_textfile.txt"))) //delete temporary text file
            {
                File.Delete(string.Concat(Directory.GetCurrentDirectory(), "\Temp_textfile.txt"));
            }
            backgroundWorker1.ReportProgress(100);
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error occurred!\n" + ex, "Error Window", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            addfiles.Text = "Add Files";
            export.Text = "Export!";
            numFiles.Clear();
            addfiles.Enabled = true;
            export.Enabled = true;
        }
    }

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

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show("Done exporting!", "Notification Window", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
        addfiles.Text = "Add Files";
        export.Text = "Export!";
        numFiles.Clear();
        addfiles.Enabled = true;
        export.Enabled = true;
    }
}

我不明白这里有什么问题。有人能给我指出正确的方向吗?

backgroundWorker1.ReportProgress(((i / real_length) * 75) + 15);

问题是 (i / real_length) returns 0 因为您使用的是 integer division.

相反,您需要这样做:

backgroundWorker1.ReportProgress((int)((((double)i / real_length) * 75) + 15));

或:

backgroundWorker1.ReportProgress(i * 75 / real_length + 15);

我会推荐前者。