views:

374

answers:

3

I hava a Background Worker and a DataGrid in my c# Application. In do work of my Backgroundworker which will call an Api in my dlls which will enter some Data in a SQLite Database. After the Completion of my Api call I report a progress and In progress event of my Backgroundworker I get the contents from Db and assign it as a DataSource to my grid. I call same API in same backgroundworker. In the middle of processing my application crashes. But If I dont assign the dataSource in ProgressChanged my application doesnt crashes.

+3  A: 

I am assuming you must be accessing UI object using Invoke method.

If not try using following approach (Executes the specified delegate, on the thread that owns the control's underlying window handle, with the specified list of arguments.):


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



Rakesh Gunijan
The whole point of BackgroundWorker is that you don't need to explicitly use BackgroundWorker.
Jonathan Allen
+1  A: 

It shouldn't matter, but why are you using ProgressChanged instead of RunWorkerCompleted?

Also, try doing everything on the GUI thread without the BackgroundWorker. That will let you know if the problem is in your code or how your code interacts with the GUI.

Jonathan Allen
A: 

As Johnathan Allen mentions, it should not matter. Unless something else is going on. I have had two cases where I could not interact with certain controls in the events generated by the BackgroundWorker. The only thing that worked was using the Invoke method.

Try assigning the DataSource on the same thread that created the DataGridView control. You do this through the control's Invoke method. Use the following code. (I have not tested, but this is the standard pattern.)

If this does not work then try Jonathan Allen's suggestion.

Actually, do whichever suggestion is easiest to try first.


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