我有一个使用一个类的Windows窗体应用程序(其名称为Parser
)
这个表单有一个按钮,当我点击windows窗体应用程序按钮时,它会调用一个解析器类方法。
此方法只需逐行读取文本文件并将每行写入单独的文件...
我想在表单中添加一个进度条以显示进度(这是一个非常大的文件)
任何想法怎么做?我在Parse class 2属性中有一个用于文件中的行数,第二个已经检查了多少行。
这是我的button2_Click
功能
private void button2_Click(object sender, EventArgs e)
{
if (this.textBox1 != null & this.textBox2 != null)
{
inst.init(this.textBox1.Text, this.textBox2.Text);
//this.progressBar1.Show();
inst.ParseTheFile();
System.Windows.Forms.MessageBox.Show("Parsing finish successfully");
}
}
答案 0 :(得分:2)
你可以这样做:
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem((obj) =>
{
var lines = File.ReadLines(@"D:\test.txt");
var count = lines.Count();
for(int i = 0; i < count; i++)
{
// some parse work
Invoke(new Action(() =>
{
progressBar1.Value = (i * 100) / count;
}));
}
});
}
在上面的示例中,它只是创建一个后台线程,以便在调用Invoke
方法之前不阻止UI线程。
Invoke
方法是必要的,以便使用当前线程不是所有者的Control
进行操作。它需要一个委托,并在拥有Control
。
如果将foreach
循环并行,你甚至可以走得太远,如果解析这些行是一项耗时的任务。一个例子:
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem((obj) =>
{
var lines = File.ReadLines(@"D:\test.txt");
var count = lines.Count();
Parallel.For(0, count, i =>
{
// some parse work
Invoke(new Action(() =>
{
progressBar1.Value = (i * 100) / count;
}));
});
});
}
答案 1 :(得分:1)
当然你必须把你的ParseTheFile代码移到这里。
对于更高级的东西,有几个选项:
ParseTheFile
(例如Action)ParseTheFile
返回IObservable表示进度的Control.Invoke ParseTheFile
用来表示进度(不建议)(请注意,大多数此选项需要使用{{3}}返回UI-Thread以设置进度条值,如果您使用另一个线程 - 我建议您使用另一个线程,如果文件是那么大)
对于初学者,我会选择背景工作者 - 恕我直言,如果您不想在第一次运行时使用SOLID(desing patterns / priciples),这很好;)
答案 2 :(得分:0)
只需使用Math来计算百分比 喜欢:
//While Reading
NumOfLines++;
int Percentage = (NumOfLines * 100) / TotalLines ;
ProgressBar.Value = Percentage;
并且可能放入int.ParseTheFile();进入后台工作者和/或线程内。