Tuesday, February 23, 2010

Updating Controls Data in Multithreaded Environment

If you are developing a multithreaded Windows application, there are high chances that data for a single control is being generated by many threads. In other words, any thread can raise a request to update the control which is owned by some other thread. If you are a .Net developer using .Net versions 2.0 onwards, accomplishing the request is not straight forward case. .Net 2.0 onwards, cross thread operations are not permitted (correct word - ‘advised’).

There are several ways in which you can accomplish this:

· This exception is raised by Visual Studio only. If you will run the application out of Visual Studio, CLR will never complain about the cross thread operation.

Therefore, you can use this simple (Bad though) syntax

Control.Data = data;

· If you are really worried about the testing team ( And not about the application ) that any tester might complain this error while testing the code through Visual Studio, then you can suppress this exception also. You need to instruct Visual Studio to shut up on any cross thread operation:

CheckForIllegalCrossThreadCalls = false;

· If you are concerned about the application and have sense of good programming, then I don’t think above two Options are good for you. One way is to use the invoke method on the control. Each control has a property [Control.InvokeRequired] which can tell you whether control has been created by the current thread or any other thread.

You can use Invoke method to update the control’s state.

** UpdateUIDel -> Delegate

** UpdateUI ->Method to update the controls’ state (i.e. text in a textbox).

delegate void UpdteUIDel(int a);

private void UpdateUI(Object a)

{

textBox1.Text = a.ToString();

}

// Call Invoke on Form itself

this.Invoke(new UpdteUIDel(UpdateUI), val);

· Here is the last method which I think is the best way to solve the problem. .Net does provide SynchronizatinContext class for propagating a synchronization context in various synchronization models. For Windows forms, corresponding context class is the WindowsFormsSynchronizationContext which provides a synchronization context for the Windows Forms application model and is the child class of the SynchronizatinContext.

This class takes the responsibility to identify the control’s owner and updates the control via the same owner.

WindowsFormsSynchronizationContext context = new

WindowsFormsSynchronizationContext();

SendOrPostCallback updateDel = new SendOrPostCallback(UpdateUI);

// Syncronous Method

context.Send(updateDel, val);

// Asynchronous Methods

// context.Post(updateDel, val);

Send is synchronous call (similar to Invoke )

Post is asynchronous call (similar to BeginInvoke)

No comments:

Post a Comment