tags:

views:

1309

answers:

7

when you data bind in C#, the thread that changes the data causes the control to change too. but if this thread is not the one on which the control was created, youll get the above exceptions.

surfed the net - no good answer.

anyone ?

+1  A: 

If the data modification is not too time consuming (meaning, if the main purpose of the background thread is not the actual data modification), try moving the section that modifies the data to a delegate and Invoke'ing that delegate.

If the actual heavy work is on the data, you'll probably have to create a deep copy of this data to pass to the background thread, which will send the processed data back to the UI thread via Invoke again.

Ishmaeel
+2  A: 

You should be able to do something like:

if (control.InvokeRequired)
{
control.Invoke(delegateWithMyCode);
}
else
{
delegateWithMyCode();
}

InvokeRequired is a property on Controls to see if you are on the correct thread, then Invoke will invoke the delegate on the correct thread.

UPDATE: Actually, at my last job we did something like this:

private void SomeEventHandler(Object someParam)
{
if (this.InvokeRequired)
{
this.Invoke(new SomeEventHandlerDelegate(SomeEventHandler), someParam);
}

// Regular handling code
}

which removes the need for the else block and kind of tightens up the code.

Mike Stone
+1  A: 

As I don't have a test case to go from I can't guarantee this solution, but it seems to me that a scenario similar to the one used to update progress bars in different threads (use a delegate) would be suitable here.

public delegate void DataBindDelegate();
public DataBindDelegate BindData = new DataBindDelegate(DoDataBind);

public void DoDataBind()
{
DataBind();
}

If the data binding needs to be done by a particular thread, then let that thread do the work!

tags2k
A: 

guess I am missing something. isnt the whole purpose of databinding is to avoid any code but the binding ? what will the (delegate)function do, update the control ? I am trying to avoid writing this code ... by using data binding ...

thanks.

gil
+1  A: 

Re: 2004

No, you will only move the code that changes the data into the delegate function (because the data change is what triggers the control update). Other than that, you should not have to write anything extra.

Ishmaeel
A: 

If the thread call is "illegal" (i.e. the DataBind call affects controls that were not created in the thread it is being called from) then you need to create a delegate so that even if the decision / preparation for the DataBind is not done in the control-creating thread, any resultant modification of them (i.e. DataBind()) will be.

You would call my code from the worker thread like so:

this.BindData.Invoke();

This would then cause the original thread to do the binding, which (presuming it is the thread that created the controls) should work.

tags2k
A: 

In WPF and Silverlight the binding infrastructure takes care of the switching to the UI thread.

Brian Leahy