views:

215

answers:

2

I have a Silverlight 3 page. I use a System.Threading.Timer to perform an Asynchronous WCF service call. I make the call by passing in the Silverlight page class ("this") in as the "state" object in the timer constructor, and accessing the service client proxy through it. By doing it this way, the callback from the WCF service fires fine.

My problem (as I understand it) is that the return from the WCF call occurs in a separate thread, and thus I get an access error when I attempt to access/modify the UI elements on the Silverlight page.

First, is my understanding of the problem correct?

Second, what is the most architucturally correct method of solving this problem?

Thank you for any assistance.

+1  A: 

Found the answer: I needed to wrap the callback code in:

this.Dispatcher.BeginInvoke(() => { code here });

More info: http://msdn.microsoft.com/en-us/library/ms591206.aspx

Sako73
+2  A: 

Using this.Dispatcher.BeginInvoke is necessary to move code execution on the thread that has access to UI elements. However some thought may be worth applying. It may be easy to simply do this:-

 this.Dispatcher.BeginInvoke(() => {

      // The whole body of code needed
 });

However there are a couple of things to consider. If the whole bunch code is going to do any significant work that doesn't involve access to UI elements it may be better to do that first then switch to the UI thread only when you've got everything together to modify the UI. This may mean changing the order about which things happen, perhaps even employing a few variables to hold onto values until later.

Secondly if the same call back is used very frequently from UI thread itself then it may be better to re-arrange the code code these callbacks run the code straight with out the use of seondary function call or BeginInvoke. Dispatchers CheckAccess method can help you determine whether BeginInvoke is needed. However in your specific scenario BeginInvoke will allways be needed.

AnthonyWJones