Back in this post I showed you how you can have a look at the original source code of .NET, including original comments and variable names. In this post we’ll see a few interesting things about WPF’s Dispatcher class. But first some background on the subject. WPF Thread AffinityAlmost every WPF element has thread affinity. This means that access to such an element should be made only from the thread that created the element.
In order to do so, every element that requires thread affinity is derived, eventually, from DispatcherObject class. This class provides a property named Dispatcher that returns the Dispatcher object associated with the WPF element. The Dispatcher classThe Dispatcher class is used to perform work on his attached thread. It has a queue of work items and it is in charge of executing the work items on the dispatcher thread.So, when you want to change a property of a WPF element from a thread different of the one who created the element, you should use the element’s Dispatcher property to dispatch the operation to the correct thread. This is done using the BeginInvoke method that accepts a method to be invoked. Where is the Dispatcher of the thread saved?Every thread should have their dispatcher object, so you would think they will save the dispatcher on the Thread Local Storage (TLS).It turns out they store a static list of all available dispatcher objects.
Of course, this list is synchronized using a private global static object (this is a common best practice when locking object).Whenever the dispatcher of an object is needed, they go over the list, comparing the dispatcher’s Thread property with the current thread, until they find the correct dispatcher object for this thread. The reason, as they note in the comments is that managed TLS is rather expensive.Above this list they add the following optimization: before going over the dispatchers list they check if the last given dispatcher is suitable, so only a thread context switch will derive a new list search. Read more: Arik Poznanski's Blog
In order to do so, every element that requires thread affinity is derived, eventually, from DispatcherObject class. This class provides a property named Dispatcher that returns the Dispatcher object associated with the WPF element. The Dispatcher classThe Dispatcher class is used to perform work on his attached thread. It has a queue of work items and it is in charge of executing the work items on the dispatcher thread.So, when you want to change a property of a WPF element from a thread different of the one who created the element, you should use the element’s Dispatcher property to dispatch the operation to the correct thread. This is done using the BeginInvoke method that accepts a method to be invoked. Where is the Dispatcher of the thread saved?Every thread should have their dispatcher object, so you would think they will save the dispatcher on the Thread Local Storage (TLS).It turns out they store a static list of all available dispatcher objects.
Of course, this list is synchronized using a private global static object (this is a common best practice when locking object).Whenever the dispatcher of an object is needed, they go over the list, comparing the dispatcher’s Thread property with the current thread, until they find the correct dispatcher object for this thread. The reason, as they note in the comments is that managed TLS is rather expensive.Above this list they add the following optimization: before going over the dispatchers list they check if the last given dispatcher is suitable, so only a thread context switch will derive a new list search. Read more: Arik Poznanski's Blog
0 comments:
Post a Comment