BackgroundWorker In Form.Load event
本文关键字:event Load Form In BackgroundWorker | 更新日期: 2023-09-27 18:27:58
我在一个带有vs2010和本地数据库的c#windows应用程序中工作。在我的一个表单中,我使用BindingNavigator和一组由数据库和ReporViewer填充的文本框。我添加了一个后台工作程序,以便在数据库中有大量记录的情况下填充表适配器。
问题是,当我调试应用程序时,我使用后台工作程序的方式在文本框中看不到任何数据,否则当我运行应用程序时它工作正常。我知道这是在非UI线程上访问UI的情况,这是错误的。还有别的办法吗?提前谢谢。
这是我正在使用的代码:
private void Client_Load(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
this.clientTableAdapter.Fill(this.database1DataSet.Client);
this.projectTableAdapter.Fill(this.database1DataSet.Project);
if (InvokeRequired)
{
this.Invoke(new MethodInvoker(this.reportViewer1.RefreshReport));
return;
}
}
通常,后台工作程序在同一个线程上返回,并且实际上会抛出关于非UI线程的异常。然而,在你的情况下,这可能会被吃掉。您应该将RunWorkerCompleted
事件用于主要工作完成后发生的项目,尤其是在希望更新UI时。而且,这个应该返回到上面提到的从(在您的例子中是UI)调用它的同一个线程。
因此,我将把您的UI处理代码(RefreshReport
)移到为RunWorkerCompleted设置的新方法中。
然而,我的建议是查看任务并行库。它最终使代码更干净,更容易调试IMO.
示例(由于null,可能无法编译,但您可以获得jist:):
var task = Task.Factory.StartNew(()=>{//Do Async Stuff});
task.ContinueWith((previousTask)=>{//Do your UI Stuff}, null, null,
TaskScheduler.FromCurrentSynchronizationContext);
//The FromCurrentSync makes sure the method returns
//to the same thread (UI in this case) that it started
我知道这不是一个直接的答案,而是一个我认为更干净、更可调试的方法的建议。