BackgroundWorker WPF与Progress Bar的困难

我正在开发一个WPF,C#应用程序,我必须读取一个非常大的CSV文件并写入数据库。 这个过程需要很长时间,所以我想至少显示一个随着接近完成而增长的进度条。

现在,我在顶部有以下代码:

private readonly BackgroundWorker worker = new BackgroundWorker(); 

然后在循环内我有这个:

 worker.WorkerReportsProgress = true; worker.ReportProgress((100 * i) / 10000); 

我有一个这样的私人子:

 private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { prgBar.Value = Math.Min(e.ProgressPercentage, 100); } 

但我没有看到进度条更新或发生任何事情,程序仍然挂起。 难道我做错了什么?

更新:在这里尝试了MSDN指南http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx ,我不知道如何使用该示例。 我当然调整了循环部分。 嘿。 它仍然闲置,没有任何更新。 哎呀,我想做的就是得到一个小的计数器,每次读取和添加一行时都会增加。

更新的代码:

  private BackgroundWorker bw = new BackgroundWorker(); public Process() { bw.WorkerReportsProgress = true; bw.WorkerSupportsCancellation = true; bw.DoWork += new DoWorkEventHandler(bw_DoWork); bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); } private void bw_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; // Perform a time consuming operation and report progress. int d = 0; Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); // Set filter for file extension and default file extension dlg.DefaultExt = ".csv"; dlg.Filter = "CSV File (*.csv)|*.csv"; dlg.Title = "file"; // Display OpenFileDialog by calling ShowDialog method Nullable result = dlg.ShowDialog(); if (result == true) { // Open document string filename = dlg.FileName; List fileContent = new List(); using (FileStream reader = File.OpenRead(@filename)) // mind the encoding - UTF8 using (TextFieldParser parser = new TextFieldParser(reader)) { using (SqlConnection conn = new SqlConnection(Classes.PublicVariables.Connection)) { parser.Delimiters = new[] { "," }; parser.HasFieldsEnclosedInQuotes = true; while (!parser.EndOfData) { string[] line = parser.ReadFields(); fileContent.Add(line); SqlCommand comm = QUERYANDPARAMETERS d += 1; comm.ExecuteNonQuery(); worker.ReportProgress((d * 10)); } } } } private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { lblCount.Content = "Complete"; } private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) { this.lblCount.Content = (e.ProgressPercentage.ToString() + "%"); } 

当工人跑步时我得到一个摘录。

  An exception of type 'System.NullReferenceException' occurred inSolution.exe but was not handled in user code 

附加信息:对象引用未设置为对象的实例。

UPDATE3

搞定了! 我需要的只是与上面相同的代码,但是:

  if (bw.IsBusy != true) { bw.RunWorkerAsync(); } else { bw_DoWork(null, null); } 

在按钮的事件处理程序中按。

这不会按原样编译,但应该让你开始正确的方向:

 private readonly BackgroundWorker worker = new BackgroundWorker { WorkerReportsProgress = true }; public MainWindow() { InitializeComponent(); worker.DoWork += worker_DoWork; worker.ProgressChanged += worker_ProgressChanged; } private void worker_DoWork(object sender, DoWorkEventArgs doWorkEventArgs) { // Do some long process, break it up into a loop so you can periodically // call worker.ReportProgress() worker.ReportProgress(i); // Pass back some meaningful value } private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { prgBar.Value = Math.Min(e.ProgressPercentage, 100); } 

变量i int? 如果是,则(100 * i) / 10000将返回0i <100 。 并且ReportProgress方法的参数应该是一个precent值。 你可以把它改成worker.ReportProgress(i); ,试试吧。