Reputation: 146557
We know that it is not possible to execute code that manipulates the properties of any UI element from any thread other than the thread the element was instantiated on... My question is: Why?
I remember that when we used COM user interface elements, (in COM/Visual Basic 6.0 days), that all UI elements were created using COM classes and co-classes that stored their resources using a memory model referred to as Thread-Local-Storage (TLS), but as I recall, this was required because of something related to the way COM components were constructed, and should not be relevant to .NET UI elements. What's the underlying reason why this restriction still exists?
Is it because the underlying Operating System still uses COM-based Win32 API classes for all UI elements, even the ones manipulated in a managed .NET application?
Upvotes: 8
Views: 476
Reputation: 97821
AFAIK, it's more basic than even COM. It goes right down to the good ol' Windows API. I believe that windows in Windows are expected to be owned by a thread, period. Each thread has its own message pump, dispatching messages to the windows it owns. It's a pretty fundamental construct of Windows -- maybe a bit archaic these days, but fundamental.
My sense of it is that this thread affinity helps for interoperability when you need to integrate WPF into Windows Forms applications, or if you need to monkey with a Windows object somewhere else in your application using a HWND that you got somewhere... It probably also is what allows older versions of Windows (XP) to host WPF applications without any major architectural changes to the OS itself.
Upvotes: 2
Reputation: 36102
It sounds like you're referring to WPF rather than generic Windows API programming. I'm no expert on WPF internals, but here are a few items on why keeping UI manipulations in one UI thread are a good idea:
That last item is Win API related. When a window handle is created, it is bound to the thread that issued the CreateWindow call. Messages sent to that window handle will be placed in the message queue associated with that thread. If that thread does not process window messages, the window will be non-responsive - UI frozen. If another thread tries to SendMessage to that window, that thread will also be frozen waiting for the synchronous call to complete. This snowballs pretty quickly into ugliness all over. This is why it's important to make sure that you only create window handles on threads that are prepared to process window messages.
Why is a window handle's message queue bound to a specific thread? I don't know, but I'm sure the answer is not trivial.
Upvotes: 1
Reputation: 8531
From http://msdn.microsoft.com/en-us/library/ms741870.aspx:
Historically, Windows allows UI elements to be accessed only by the thread that created them. This means that a background thread in charge of some long-running task cannot update a text box when it is finished. Windows does this to ensure the integrity of UI components. A list box could look strange if its contents were updated by a background thread during painting.
Upvotes: 0