Progressbar在阅读流时不工作
我已经看到很多关于进度条和多线程的问题和帖子,所以我希望我不要问一个其他地方已经回答的问题。但如果我这样做,我的应用,我试图找到一个解决方案。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("&", "&"));
}
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)
{
}
}
}
您也在筹集太多活动。你不应该为每一行解析出一个事件。这将填满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.
}
}
也使用(我* 100.0/totalNumberOfLines)强制执行双除法(否则它将始终返回0) – 2013-03-19 16:09:03
我没有使用该语句:双百分比=(i ++ * 100.0)/计数; worker.ReportProgress((int)Math.Round(percentage,0)); – 2013-03-19 16:16:10
@MartijnBurger你使用了'100',而不是'100.0'。差异是显着的。第一个使用整数除法,所以结果被截断。第二个是'double',所以它执行浮点除法。你想要后者。 – Servy 2013-03-19 16:17:22
添加Debug.WriteLine()以仔细检查%完成值的发送方式。我不确定计算结果。 – 2013-03-19 16:08:30