0
votes

I have been developing a Lync Silverlight application in Silverlight and now I am trying to shift it to WPF.

However, I am facing some thread affinity issues. For example I display the Lync client's state on my page in a textblock, and so in my code behind have wired a state changed event handler, that writes the new state into the textblock whenever the state of Lync client changes.

Now, this worked perfectly in silverlight but seemingly is not allowed in WPF. Now my questions are:

  1. How come it works in Silverlight bt not in WPF, even though Silverlight is supposed to be a subset of WPF?

  2. Thread affinity is an important concept and I know we can use invoke dispatcher, but doesn't it just beat the concept of asynchronous programming in form of event handlers and callbacks?

  3. I have a button defined in my XAML page, and the click event handler defined on it can access other UI elements, it does not suffer the problem outlined above.

    But if I define a LyncClient instance in my code-behind, event handlers defined on it cannot access the UI elements. Why so, I detected no such difference between UIElements and other objects in Silverlight?

1
Can you clarify what object / api is raising the events to your app in SL and in WPF? It almost sounds like the one in SL is raising the event on the UI thread, whereas the one in WPF is raising it on a background thread. - NathanAW
Hi Nathan, thanks for your interest. I have a button on my page, on which i have a click event defined, and in my code behind i use LyncClient.GetClient() to get a LyncCLient object for which i have defined an event handler for state changed event. Now, in silverlight i was able to make changes to UI elements in both the event handlers. But in WPF, i can only make changes to UI in the click event handler. If I try to access UI objects in the LyncClient State Changed event handler, I get the error - invalid thread access. - Akshay at IITD
Is the LyncClient something you wrote, or is it part of an API that was provided by Microsoft or other third party? I'm wondering if they implemented it differently between the Silverlight version and the WPF version. - NathanAW
It is an API by MS only...I have gone through a lot of MS documentation on SL but not found any reference to thread affinity concepts (in all the egs i saw they seamlessly used callbacks & event handlers)...i think that since silverlight applications are meant to be run in browsers, they do not have the same threading model as wpf applications which are meant to run on the operating system...so what i say is maybe silverlight apps dont have to comply with thread affinity restrictions...i warn you though - this is only my own inference i have not found any such thing written anywhere :P - Akshay at IITD
as to why, the event handlers defined on UI elements like button can access UI elements and event handlers on objects defined in code behind cant....i think event handlers for ui objects would run in ui threads only and for objects defined in codebehind they would run on a background thread.. - Akshay at IITD

1 Answers

0
votes

Based on above comments, I'll suggest the following "answer"...

I would guess it is more likely than not that there is some sort of different in the way that the SL API was written than that of the WPF api. That could explain the difference in the thread that is used when the API issues the callback. To verify this, you could:

  1. Ask MS directly
  2. Put some diagnostics code in your callback method to log the thread ID and compare that to the main thread of the application. Do this for both SL and WPF to see if they are the same or different threads.
  3. Open the assemblies in Reflector to inspect how each API was written.

In terms of handling this specific situation, in your callback, you could:

  1. Get the dispatcher object (different for SL than WPF) and always issue UI updates through Dispatcher.Invoke.
  2. Use databinding and INotifyPropertyChanged to insulate the UI from the property. You could delcare a property on a ViewModel or in the code behind. Then bind the UI's textbox to that property. Databinding has some smarts in it that will automatically marshal property changes to the correct thread (in most cases anyway).

Hope that helps.