我目前正在开展一个有趣的项目。这是一个C#WinForms项目。基本上,应该使用Visual Studio解决方案文件,然后应用程序解析它:根据文件中的内容构建对象等等(解释它的详细内容与问题无关,所以我&#39 ;停在这里。)
我有一个主窗体(frmMain
),它提供了加载文件的界面,还有一个进度条(analyzingProgressBar
)应该来显示进度文件解析,因为它需要几秒钟。我已经设置了BackgroundWorker
,但我被卡住了 - 如何根据实际进度更新prgressbar?
我的代码是:
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;
}
}
答案 0 :(得分:1)
通常,要显示进度如何变化,您需要在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
设为“Marquee”;在启动线程之前显示它并将其隐藏在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);
...
}