代码之家  ›  专栏  ›  技术社区  ›  Crescendo26

Backgroundworker未更新ProgressBar,尽管DoWork循环正在运行[重复]

  •  0
  • Crescendo26  · 技术社区  · 7 年前

    我的程序应该允许用户选择多个文本文件,将内容编译成单个文本文件,然后将其导出到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;
        }
    }
    

    我似乎不知道这里有什么问题。有人能给我指一下正确的方向吗?

    1 回复  |  直到 7 年前
        1
  •  0
  •   mjwills Myles McDonnell    7 年前
    backgroundWorker1.ReportProgress(((i / real_length) * 75) + 15);
    

    问题是 (i / real_length) 返回0,因为您正在使用 integer division .

    相反,你需要做:

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

    或:

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

    我推荐前者。