C#后台工作者更新状态标签

这应该是一件相当简单的事情; 但是,我一直无法弄清楚这一点。

/// This section is located in the InitializeComponent() method /// form's class, ie partial class frmMain { .... } this.bgw = new System.ComponentModel.BackgroundWorker(); this.bgw.WorkerReportsProgress = true; this.bgw.DoWork += new System.ComponentModel.DoWorkEventHandler(this.bgw_DoWork); this.bgw.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.bgw_ProgressChanged); /// This code is located in public partial class frmMain : Form { .... } private void bgw_DoWork(object sender, DoWorkEventArgs e) { for (int i = 1; i <= 100; i++) { Thread.Sleep(100); // Wait 100 milliseconds //Console.WriteLine(i); bgw.ReportProgress(i); } } private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e) { // Update status label lblStatus.Text = e.ProgressPercentage.ToString(); } // New code added to question after edit public frmMain() { InitializeComponent(); bgw.RunWorkerAsync(); // some more stuff... } 

后台工作者正常运行; 但是,它没有正确更新其进度。 如果我取消注释DoWork事件中的注释行,我能够正确地看到状态更新; 但是,在主线程中的任务(繁重的数据库计算内容)完成之后,才会触发ProgressChanged事件。

这是使用.NET Framework 4并且是Windows窗体应用程序。

编辑

请参阅上面代码中的注释,了解代码所在的位置。

更多细节

正在执行的代码涉及在数据库上执行多个查询。 我无权披露该代码。 至于代码是如何执行的,我实际上不知道,因为我被另一个开发人员交给了.dll并被告知只在访问数据库时才使用它….

编辑

“更多东西”部分中的代码被移动如下

 private void frmMain_Load(object sender, EventArgs e) { // some more stuff... aka run queries! } 

你的BackgroundWorker代码很好。 问题是你在其他地方(在这种情况下,在你的构造函数或FormLoad )有阻塞UI线程的代码(通过执行同步数据库请求)。 您需要做一些事情来确保此代码在非UI线程中运行。 这可能意味着使用现有的BackgroundWorker来执行其他长时间运行的任务; 它也可以通过使用Task.Factory.StartNew或其他一些线程机制来完成,让它在非UI线程中运行。

一旦UI线程未被阻止,您将看到在您的`ProgressChanged事件处理程序中进行的更新反映在UI中。

@Servy当然是正确的。

我只是想用这个代码重现问题:

 public partial class Form1 : Form { public Form1() { InitializeComponent(); bgw.RunWorkerAsync(); Task.Factory.StartNew(SomeMoreStuff); } private void SomeMoreStuff() { for (int i = 0; i < 5; i++) { Thread.Sleep(50); this.Invoke((Action)HogTheUIThread); } } private void HogTheUIThread() { Thread.Sleep(1000); } private void bgw_DoWork(object sender, DoWorkEventArgs e) { for (int i = 1; i <= 100; i++) { Thread.Sleep(100); // Wait 100 milliseconds //Console.WriteLine(i); bgw.ReportProgress(i); } } private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e) { // Update status label lblStatus.Text = e.ProgressPercentage.ToString(); } }