BindingSource and Cross-Thread exceptions
Here is the part of the above example that solves this problem:
button.Click += (_, __) =>
{
// Create another thread that does something with the data object
var worker = new BackgroundWorker();
worker.DoWork += (___, _____) =>
{
for (int i = 0; i < 10; i++)
{
// This doesn't lead to any cross-thread exception
// anymore, cause the binding source was told to
// be quiet. When we're finished and back in the
// gui thread tell her to fire again its events.
myData.MyText = "Try " + i;
}
};
worker.RunWorkerCompleted += (___, ____) =>
{
// Back in gui thread let the binding source
// update the gui elements.
bindingSource.ResumeBinding();
button.Enabled = true;
};
// Stop the binding source from propagating
// any events to the gui thread.
bindingSource.SuspendBinding();
button.Enabled = false;
worker.RunWorkerAsync();
};
So this doesn't lead to any cross-thread exceptions anymore. The drawback of this solution is that you won't get any intermediate results shown within the textbox, but it's better than nothing.
You can't update the BindingSource from another thread if it's bound to a winforms control. In your MyText setter you must Invoke
PropertyChanged on the UI thread rather than running it directly.
If you want an extra layer of abstraction between your MyText class and the BindingSource you can do that, but you can't separate the BindngSource from the UI thread.
In Windows Froms
In cross thread i just used
// this = from on which listbox control is created.
this.Invoke(new Action(() =>
{
//you can call all controls it will not raise exception of cross thread
//example
SomeBindingSource.ResetBindings(false);
Label1.Text = "any thing"
TextBox1.Text = "any thing"
}));
and VOILA
/////////// Edit //////////
If there is chance of call from same thread it is created on then add following check
// this = from on which listbox control is created.
if(this.InvokeRequired)
this.Invoke(new Action(() => { SomeBindingSource.ResetBindings(false); }));
else
SomeBindingSource.ResetBindings(false);