2013-03-19 58 views
0

我已经看到很多关于进度条和多线程的问题和帖子,所以我希望我不要问一个其他地方已经回答的问题。但如果我这样做,我的应用,我试图找到一个解决方案。Progressbar在阅读流时不工作

我有一些大的文件,我想通过&更换&由于这些文件比较大,我想忒看到statusupdate飘飞文档多远解析。我编写的代码用于替换&符号,但是,只有在文档解析完成后才能完成进度更新。任何想法有什么不对?

using System; 
using System.Windows; 
using Microsoft.Win32; 
using System.Text; 
using System.Xml; 
using System.IO; 
using System.Diagnostics; 
using System.Data.SqlClient; 
using System.Data; 
using System.Text.RegularExpressions; 
using System.ComponentModel; 

namespace DigiPort 
{ 
    public partial class MainWindow : Window 
    { 

     public string filename; 
     public string xmlfilename; 
     BackgroundWorker worker = new BackgroundWorker(); 

     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private void onImportDocClicked(object sender, RoutedEventArgs e) 
     { 
      OpenFileDialog ofd = new OpenFileDialog(); 
      ofd.Filter = "Text documents (.txt)|*.txt"; 
      Nullable<bool> result = ofd.ShowDialog(); 
      if (result == true) 
      { 
       OutPutWindow.Text = "Document wordt nu gelezen."; 
       filename = ofd.FileName; 
       worker.DoWork += new DoWorkEventHandler(ReplaceAmpersandAsync); 
       worker.ProgressChanged += new ProgressChangedEventHandler(ProBarChanged); 
       worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ReplaceAmpersandCompleted); 
       worker.WorkerReportsProgress = true; 
       worker.ReportProgress(0, "Start counting lines"); 
       int count = ReadNumberOfLines(); 
       worker.ReportProgress(0, "Lines counted. Total number of lines is: " + count); 
       worker.RunWorkerAsync(count); 
       OutPutWindow.Text = "Document gelezen en ampersands vervangen."; 
      } 
     } 

     private int ReadNumberOfLines() 
     { 
      int count = 0; 
      using (FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
      using (BufferedStream bs = new BufferedStream(fs)) 
      using (StreamReader sr = new StreamReader(bs)) 
       while (!sr.EndOfStream) 
       { 
        sr.ReadLine(); 
        count++; 
       } 
      return count; 
     } 

     private void ReplaceAmpersandAsync(object sender, DoWorkEventArgs e) 
     { 
      int i = 0; 
      int count = (int)e.Argument; 
      xmlfilename = filename + ".xml"; 
      StreamWriter writer = new StreamWriter(xmlfilename); 
      using (FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
      using (BufferedStream bs = new BufferedStream(fs)) 
      using (StreamReader sr = new StreamReader(bs)) 
      while (!sr.EndOfStream) 
      { 
       double percentage = (i++ * 100)/count; 
       worker.ReportProgress((int)Math.Round(percentage, 0)); 
       if (i % 100000 == 0) 
       { 
        worker.ReportProgress(i, "Linenumber " + i + " is now parsed"); 
       } 
       string content = sr.ReadLine(); 
       writer.WriteLine(content.Replace("&", "&amp;")); 
      } 

      writer.Close(); 
      worker.ReportProgress(i, "All lines are parsed, file is saved"); 
     } 

     private void ProBarChanged(object sender, ProgressChangedEventArgs e) 
     { 
      ProBar.Value = e.ProgressPercentage; 
      OutPutWindow.Text += (string)e.UserState; 
     } 

     private void ReplaceAmpersandCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
     } 
    } 
} 
+0

添加Debug.WriteLine()以仔细检查%完成值的发送方式。我不确定计算结果。 – 2013-03-19 16:08:30

回答

3

您也在筹集太多活动。你不应该为每一行解析出一个事件。这将填满Windows消息队列,并且不能跟上。每次你有一些重大进展时(例如每完成1%提高一个事件),每次只举一个事件。

另外,ReportProgress的第一个参数应该是介于0到100之间的百分比,表示工作的完成程度。您在这里滥用它返回一个行号:

worker.ReportProgress(i, "Linenumber " + i + " is now parsed"); 

而且,这也是值得一提的是您目前正在吞噬你的代码可以生成任何异常。在完成的事件处理程序中,您应该检查是否有错误:

private void ReplaceAmpersandCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Error != null) { 
     // Show the user an error message. 
    } 
} 
+2

也使用(我* 100.0/totalNumberOfLines)强制执行双除法(否则它将始终返回0) – 2013-03-19 16:09:03

+0

我没有使用该语句:双百分比=(i ++ * 100.0)/计数; worker.ReportProgress((int)Math.Round(percentage,0)); – 2013-03-19 16:16:10

+0

@MartijnBurger你使用了'100',而不是'100.0'。差异是显着的。第一个使用整数除法,所以结果被截断。第二个是'double',所以它执行浮点除法。你想要后者。 – Servy 2013-03-19 16:17:22