Search code examples
c#multithreadingbindingsource

Cross-thread mistakes


I can't explain this with my own words, so here's the situation:

myBindingSource.Add(new myElement());
SetDataSource(myBindingSource);
myBindingSource.Add(new myElement());

I always catch an exception (a cross-thread exception) on the second call of Add. Here's the SetDataSource void:

delegate void SetDataSourceCallback(BindingSource db);
private void SetDataSource(BindingSource db)
{
        if (myDataGridView.InvokeRequired)
        {
            SetDataSourceCallback d = new SetDataSourceCallback(SetDataSource);
            myDataGridView.Invoke(d, new object[] { db });
        }
        else
        {
            myDataGridView.DataSource = db;
        }
}

I can't understand why this keep happening!


Solution

  • Use the main UI thread's dispatcher to call safely any UI code from any other thread.

    WPF cannot let you change any UI state from other thread than the "main" UI thread. So in general, if you have any state which changes UI, you should wrap it with the Dispatcher.Invoke code.

    Application.Current.Dispatcher.Invoke(new Action(() => {
       myBindingSource.Add(new myElement());
       SetDataSource(myBindingSource);
       myBindingSource.Add(new myElement());
     }));