A customer had code that used the DispatcherÂQueue.
property, but found that the code crashed when running on Windows Server 2019 systems,¹ because the HasÂThreadÂAccess
property wasn’t added until Windows Server Version 1903.
They wondered if there was a way to find out whether you are running on a DispatcherÂQueue
‘s thread without using the HasÂThreadÂAccess
property?
Well, let’s browse around the members of DispatcherÂQueue
:
Member | Available in Server 2019? |
---|---|
GetForCurrentThread | Yes |
CreateTimer | Yes |
TryEnqueue | Yes |
ShutdownStaring | Yes |
ShutdownCompleted | Yes |
HasThreadAccess | No |
It occurred to me that you can see if a particular DispatcherÂQueue
belongs to the current thread by simply reversing the question: Ask the current thread for its DispatcherÂQueue
and see if it’s the one you were given. This relies on the fact that each thread can have at most one DispatcherÂQueue
.
// Alternate version that simulates HasThreadAccess // on Windows Server 2019. // C++/WinRT bool DispatcherQueueHasThreadAccess(DispatcherQueue const& q) { ASSERT(q != nullptr); // caller should have checked this first return q == DispatcherQueue::GetForCurrentThread(); }
The customer reported back that it worked great.
A lot of computer programming is just looking at the tools you have available in your toolbox and seeing whether you can combine them in an interesting way to accomplish your goal.
¹ Still in extended support until 2029!
> This relies on the fact that each thread can have at most one DispatcherÂQueue.
Is this guaranteed? As in, documented? A link to documentation would be nice.
The CreateDispatcherQueueController function also states:
“If options.threadType is DQTYPE_THREAD_CURRENT, then a DispatcherQueue is created and associated with the current thread. An error results if there is already a DispatcherQueue associated with the current thread.”
So I would call that documented. I didn’t include to the link to the learn page here, since that makes the post go under review, but it is easy enough to find by searching for the function name.
It’s implied by the function signature: GetForCurrentThread returns a single DispatcherQueue. If a thread could have more than one DispatcherQueue, then the function signature would return a collection.