C# Form.Load事件中的BackgroundWorker
我在使用vs2010和本地数据库的c#windows应用程序中工作。在我的一个表单中,我使用BindingNavigator,其中包含一组由数据库和ReporViewer填充的文本框。我添加了一个后台工作程序,以便在数据库中有大量记录的情况下填充表适配器 问题是,当我调试我的应用程序时,我使用后台工作程序的方式在文本框中看不到任何数据,否则当我运行我的应用程序时,它工作正常。我知道这是在非UI线程上访问UI的情况,这是错误的。还有别的办法吗?先谢谢你 以下是我正在使用的代码:C# Form.Load事件中的BackgroundWorker,c#,.net,thread-safety,sql-server-ce,backgroundworker,C#,.net,Thread Safety,Sql Server Ce,Backgroundworker,我在使用vs2010和本地数据库的c#windows应用程序中工作。在我的一个表单中,我使用BindingNavigator,其中包含一组由数据库和ReporViewer填充的文本框。我添加了一个后台工作程序,以便在数据库中有大量记录的情况下填充表适配器 问题是,当我调试我的应用程序时,我使用后台工作程序的方式在文本框中看不到任何数据,否则当我运行我的应用程序时,它工作正常。我知道这是在非UI线程上访问UI的情况,这是错误的。还有别的办法吗?先谢谢你 以下是我正在使用的代码: private v
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
示例(由于空值,可能无法编译,但您可以获得jist:):
我知道这不是一个直接的答案,但更多的是对我认为更干净、更可调试的方法的建议。谢谢你的回答,但是我对这类东西比较陌生,所以我需要一个更直接的答案。我的问题是,我可以在backgroundWorker\u DoWork事件中使用tableadapter.Fill()吗?上面的代码正确吗?我使用了类似这样的代码,但还不能理解:public Task FillAync(){return Task.Factory.StartNew(()=>{this.clientTableAdapter.Fill(this.database1DataSet.Client);this.projectTableAdapter.Fill(this.database1DataSet.Project);this.reportViewer1.RefreshReport();});}现在我进一步了解了它,没有了。我将根据您的特定场景更新我的答案。但是,我仍然强烈建议您研究第三方物流,尤其是如果您是新手的话。为什么要使用旧技术开始呢?非常感谢您,我也尝试过类似的方法,而且似乎很有效。你能告诉我我是否正确吗?私有无效客户端加载(对象发送方,EventArgs e){FillAync();}公共任务FillAync(){返回任务.Factory.StartNew(()=>{this.clientTableAdapter.Fill(this.database1DataSet.Client);this.projectTableAdapter.Fill(this.database1DataSet.Project);if(InvokeRequired){this.Invoke(new MethodInvoker(this.reportViewer1.RefreshReport));return;}}});}如果它有效,那么这是一个开始,但是请查看我的更新答案。如果使用RunWorkerCompleted(在旧代码中),或者使用ContinueWith作为新代码,则不必调用。新代码类似于:var task=FillAync();task.ContinueWith((prevTask)=>{reportViewer1.RefreshReport();},new CancellationToken(),TaskCreationOptions.None,TaskScheduler.FromCurrentSynchronizationContext);但是,同样,如果它有效,这是第一步。请记住,在upvotes和accepted answers(答案旁边的复选标记)中显示赞赏。调试模式中是否存在异常?
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