2010-03-24 158 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; 
    }