在处理文件时更新进度条
本文关键字:更新 处理 文件 | 更新日期: 2023-09-27 18:17:26
我有一个有趣的项目,我目前正在工作。这是一个c# WinForms项目。基本上,使用应该加载一个Visual Studio解决方案文件,然后应用程序解析它:根据文件中编写的内容构建对象等等(详细解释它的功能与问题无关,因此我将在此停止)。
我有一个主表单(frmMain
),它提供了加载文件的接口,并且还有一个进度条(analyzingProgressBar
), 应该显示文件解析的进度,因为它需要几秒钟。我已经设置了一个BackgroundWorker
,但我卡住了-我如何根据实际进度更新进度条?
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
toolStripPseudo.Text = String.Empty;
toolStripPseudo.Spring = true;
}
private void openSolutionToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openSolutionDialog.ShowDialog() == DialogResult.OK)
{
Solution openSolution = new Solution(openSolutionDialog.FileName);
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.RunWorkerCompleted);
worker.ProgressChanged += new ProgressChangedEventHandler(this.ProgressChanged);
worker.DoWork += new DoWorkEventHandler(this.DoWork);
// start the worker thread
worker.RunWorkerAsync(openSolution);
}
}
private void DoWork(object sender, DoWorkEventArgs e)
{
// get a reference to the worker that started this request
BackgroundWorker workerSender = sender as BackgroundWorker;
Solution openSolution = e.Argument as Solution;
openSolution.AnalyzeSolution();
workerSender.ReportProgress() //What do I do here?
}
private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// TODO add graphics
}
public void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
analyzingProgressBar.Value = e.ProgressPercentage;
}
}
通常,要显示进度如何变化,您需要在DoWork
事件中进行某种循环,然后将百分比和/或消息返回UI线程:
private void DoWork(object sender, DoWorkEventArgs e)
{
var workerSender = (BackgroundWorker)sender;
// I know I'm making this up.. I have no idea what your method does/returns
var filesToAnalyze = ((Solution)e.Argument).AnalyzeSolution();
for (var i = 0; i < filesToAnalyze.Length; i++)
workerSender.ReportProgress(0, "Analyzing file #" + i);
}
因为你没有任何东西可以迭代,只是想在一个单独的后台线程中调用你的单一方法,所以不要报告进度。除非你以某种方式分解这个方法调用,否则你就无能为力了。
添加ProgressBar
, Style
设置为"选框";在启动线程之前显示它,并将其隐藏在RunWorkerCompleted
事件中:
progressBar.Show();
worker.RunWorkerAsync(openSolution);
...
private void DoWork(object sender, DoWorkEventArgs e)
{
var openSolution = (Solution)e.Argument;
// Run long method (which can't touch the UI, or it'll throw an exception)
openSolution.AnalyzeSolution();
}
private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar.Hide(); // Hide progress bar when job complete
}
AnalyzeSolution()只是在一行中调用一些(比方说,5个)其他方法。当每个方法完成时,我能做一些像在进度条上添加20%的事情吗?
是的,但是你必须调用这5个方法,而不是仅仅调用AnalyzeSolution()
:
private void DoWork(object sender, DoWorkEventArgs e)
{
var workerSender = (BackgroundWorker)sender;
var openSolution = (Solution)e.Argument;
openSolution.RunMethodOne();
workerSender.ReportProgress(20);
openSolution.RunMethodTwo();
workerSender.ReportProgress(40);
...
}