我创建了一个表单,当我打电话给我一个耗时的例程时,弹出并显示进度条。我通过UpdateProgress
方法提供我的例程进度。Backgroundworker ProgressChanged在工作完成后执行
我正在使用后台工作人员来允许用户移动窗体并在此窗体更新时继续进行业务。但是,表单只会锁定,直到例程完成,然后快速将进度条上升到100%并退出(如应该)。进度条应该与正在对UpdateProgress
方法进行调用的进程一起更新。
我在这里做错了什么?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace myNameSpace
{
public partial class ProgressIndicator : Form
{
int progressPercentage;
public ProgressIndicator()
{
InitializeComponent();
}
void progressUpdater_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// update the UI with appropriate fields
progressBar.Value = e.ProgressPercentage;
labelCommunicating.Text = "In progress: " + e.ProgressPercentage + "% complete";
}
void progressUpdater_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Close();
}
void progressUpdater_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
while (true)
{
if (progressPercentage >= 100)
{
break;
}
worker.ReportProgress(progressPercentage);
Thread.Sleep(100);
}
}
public void UpdateProgress(int progressPercentage)
{
this.progressPercentage = progressPercentage;
}
private void ProgressIndicator_Load(object sender, EventArgs e)
{
BackgroundWorker progressUpdater = new BackgroundWorker();
progressUpdater.WorkerReportsProgress = true;
progressUpdater.WorkerSupportsCancellation = true;
progressUpdater.DoWork += new DoWorkEventHandler(progressUpdater_DoWork);
progressUpdater.RunWorkerCompleted += new RunWorkerCompletedEventHandler(progressUpdater_RunWorkerCompleted);
progressUpdater.ProgressChanged += new ProgressChangedEventHandler(progressUpdater_ProgressChanged);
progressUpdater.RunWorkerAsync();
}
}
}
没有任何方式可以让您发布的代码重现问题。您在DoWork中使用Sleep(),这将永远隐藏问题。但真正的DoWork事件处理程序经常会经常调用ReportProgress。 UI线程越快,它就会开始落后。如果时间够频繁,而且没有完成其低优先级任务。就像回应用户输入或绘制控件一样。它会看起来死。人类只能以每秒25次的速度看到进展,*方式*少于淹没UI线程所需的时间。 – 2012-07-30 22:52:29
咦?完成“工作”(DoWork处理程序)时,您不会更新进度。另外,您不会显示如何调用UpdateProgress的示例。通常“进展”表示已完成工作;这是由DoWork处理程序完成的。 – 2012-07-30 23:18:46
Hans:添加了睡眠,以便应用程序不占用资源。彼得:工作在其他地方完成,“DoWork”方法在这里执行的是检查进度并相应地更新屏幕。 'UpdateProgress'方法改变了进度。 – Kashif 2012-07-31 02:58:16