October 18th, 2023

How can I check if I’m on a DispatcherQueue’s thread if I can’t call HasThreadAccess?

A customer had code that used the Dispatcher­Queue.Has­Thread­Access 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!

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

3 comments

Discussion is closed. Login to edit/delete existing comments.

  • Stephen Cleary

    > 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.

    • Me Gusta · Edited

      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.

    • Raymond ChenMicrosoft employee Author

      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.