Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Form.Load事件中的BackgroundWorker_C#_.net_Thread Safety_Sql Server Ce_Backgroundworker - Fatal编程技术网

C# Form.Load事件中的BackgroundWorker

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

我在使用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

示例(由于空值,可能无法编译,但您可以获得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