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;
    }
}

BackgroundWorker In Form.Load event

通常,后台工作程序在同一个线程上返回,并且实际上会抛出关于非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

我知道这不是一个直接的答案,而是一个我认为更干净、更可调试的方法的建议。