2010-03-24 92 views
0

我在我的c#应用程序中有一个Background Worker和一个DataGrid。在我的Backgroundworker的工作中,我将在我的dll中调用一个Api,它将在SQLite数据库中输入一些数据。完成我的Api调用后,我报告Backgroundworker的进度和正在进行的事件,我从Db获取内容并将其作为DataSource分配给我的网格。我在同一个背景工作者中调用相同的API。在处理我的应用程序崩溃的过程中。但是如果我不在ProgressChanged中分配dataSource,我的应用程序不会崩溃。从BackGroundWorker更新DataGrid

+0

你什么异常应用程序崩溃的时候? – 2010-03-24 05:44:43

+0

仅当我单独启动我的应用程序时发生崩溃 – subbu 2010-03-24 05:53:19

回答

4

我假设你必须使用Invoke方法访问UI对象。

如果不尝试使用以下方法(执行指定委托,在拥有控件的基础窗口句柄的线程,用指定的参数列表。):

 

//In Form.Designer.cs 

Label myLabel = new Label(); 


//In code behind under Background worker method 
LabelVlaueSetter SetLabelTextDel = SetLabelText; 
if (myLabel .InvokeRequired) 
{ 

    myLabel.Invoke(SetLabelTextDel, "Some Value"); 
} 

private delegate void LabelVlaueSetter(string value); 

//Set method invoked by background thread 
private void SetLabelText(string value) 
{ 
    myLabel.Text = value; 
} 


 
+1

BackgroundWorker的重点在于您不需要明确使用BackgroundWorker。 – 2010-03-24 08:02:07

1

它不应该的问题,而是为什么你使用ProgressChanged而不是RunWorkerCompleted?

此外,尝试在没有BackgroundWorker的GUI线程上做所有事情。这会让你知道问题出在你的代码中,或者你的代码和GUI的交互方式。

2

正如约翰森艾伦所提到的,这应该不重要。除非别的事情正在发生。我有两种情况,我无法与BackgroundWorker生成的事件中的某些控件进行交互。唯一有效的方法是使用Invoke方法。

尝试在创建DataGridView控件的相同线程上指定DataSource。您可以通过控件的Invoke方法执行此操作。使用下面的代码。 (我还没有测试过,但这是标准模式。)

如果这不起作用,请尝试乔纳森艾伦的建议。

其实,先做哪个建议最容易先尝试。


private delegate void SetDataSourceDelegate(object value); 

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { 
     DataTable oData = null; //'assign data source 
     if (dataGridView1.InvokeRequired) { 
      dataGridView1.Invoke(new SetDataSourceDelegate(SetDataSource), new Object[] {oData}); 
     }else{ 
      SetDataSource(oData); 
     } 
    } 

    private void SetDataSource(object value) { 
     dataGridView1.DataSource = value; 
    }