How does the Dispatcher thread work in wpf a UI control?
Edit.
If you have a long running task, delegate it to a background thread using a BackGroundWorker, and then you won't need to use the dispatcher to pass messages back to the UI. This is a very good article.
Its a very broad question. I suggest you start here with WPF Architecture.
Most objects in WPF derive from
DispatcherObject, which provides the
basic constructs for dealing with
concurrency and threading. WPF is
based on a messaging system
implemented by the dispatcher. This
works much like the familiar Win32
message pump; in fact, the WPF
dispatcher uses User32 messages for
performing cross thread calls.
There are really two core concepts to
understand when discussing concurrency
in WPF – the dispatcher and thread
affinity.
During the design phase of WPF, the
goal was to move to a single thread of
execution, but a non-thread
"affinitized" model. Thread affinity
happens when a component uses the
identity of the executing thread to
store some type of state. The most
common form of this is to use the
thread local store (TLS) to store
state. Thread affinity requires that
each logical thread of execution be
owned by only one physical thread in
the operating system, which can become
memory intensive. In the end, WPF’s
threading model was kept in sync with
the existing User32 threading model of
single threaded execution with thread
affinity. The primary reason for this
was interoperability – systems like
OLE 2.0, the clipboard, and Internet
Explorer all require single thread
affinity (STA) execution.
Given that you have objects with STA
threading, you need a way to
communicate between threads, and
validate that you are on the correct
thread. Herein lies the role of the
dispatcher. The dispatcher is a basic
message dispatching system, with
multiple prioritized queues. Examples
of messages include raw input
notifications (mouse moved), framework
functions (layout), or user commands
(execute this method). By deriving
from DispatcherObject, you create a
CLR object that has STA behavior, and
will be given a pointer to a
dispatcher at creation time.
Related
I am attempting to write a printed form in F# using WPF controls—-and do so in an asynchronous workflow. Being new to this, I can’t figure out how to place the wpf controls, consumed by the F# asynchronous block, on a STA thread, without blocking the main thread.
I have a lot of printed forms and do not want to block the main thread.
How is a STA thread created for the F# asynchronous workflow?
Thanks in advance for any help.
In pure WPF I don't think you have STA - that concept comes from the COM model. What you do have is a specific UI thread that must be used for communicating with the UI. To get that thread you can use SynchronizationContext.Current property when you are certain you are on the UI thread (e.g. in an event handler). Note: If SynchronizationContext.Current is null then you will be running in the thread pool rather than on the UI thread.
If you then pass that SynchronizationContext object into your async {} code, you should be able to rejoin the UI thread by calling Async.SwitchToContext
Why is it that the thread that created the control is the one that can update it? Why didn't MS give people the ability to use locking and other thread synchronization techniques for reading and writing to properties on UI controls with multiple threads.
The short description per MSDN is
WPF’s threading model was kept in sync with the existing User32
threading model of single threaded execution with thread affinity. The
primary reason for this was interoperability – systems like OLE 2.0,
the clipboard, and Internet Explorer all require single thread
affinity (STA) execution
The longer description is this:
Most objects in WPF derive from DispatcherObject, which provides the
basic constructs for dealing with concurrency and threading. WPF is
based on a messaging system implemented by the dispatcher. This works
much like the familiar Win32 message pump; in fact, the WPF dispatcher
uses User32 messages for performing cross thread calls.
There are really two core concepts to understand when discussing
concurrency in WPF – the dispatcher and thread affinity.
During the design phase of WPF, the goal was to move to a single
thread of execution, but a non-thread "affinitized" model. Thread
affinity happens when a component uses the identity of the executing
thread to store some type of state. The most common form of this is to
use the thread local store (TLS) to store state. Thread affinity
requires that each logical thread of execution be owned by only one
physical thread in the operating system, which can become memory
intensive. In the end, WPF’s threading model was kept in sync with the
existing User32 threading model of single threaded execution with
thread affinity. The primary reason for this was interoperability –
systems like OLE 2.0, the clipboard, and Internet Explorer all require
single thread affinity (STA) execution.
Given that you have objects with STA threading, you need a way to
communicate between threads, and validate that you are on the correct
thread. Herein lies the role of the dispatcher. The dispatcher is a
basic message dispatching system, with multiple prioritized queues.
Examples of messages include raw input notifications (mouse moved),
framework functions (layout), or user commands (execute this method).
By deriving from DispatcherObject, you create a CLR object that has
STA behavior, and will be given a pointer to a dispatcher at creation
time.
You can read the full article here
Personally I prefer WPF's single-threaded model over having to use locking and thread synchronization techniques. The Dispatcher can be used to pass messages to the main UI thread at different priority levels, which takes care of the majority of small background processes, and if you need any heavy processing then you can still create your own background thread for that.
WPF, like virtaully all UI toolkits, works by pumping a message loop. Since messages can come at any time and affect any control you would need a global lock. And to make it less error prone you probably want a function that would invoke a delegate under the lock. Perhaps something like this:
Dispatcher.Invoke(Delegate, Object())
The fact that this gets marshalled to the UI thread instead of acquiring a global lock is just an implementation detail.
I need some help understanding the difference between STA and MTA with respect to the winform and console application. I am using a third party COM interface to execute functions in parallel, using parallel.invoke. When i do this in console application everything works fine and code actually runs in parallel. But when i do the same thing in Winform it's sequential, and if i remove the STAtrhread tag above the entry point of winform , it start to work fine in parallel. Can anyone explain this behavior?,Any suggestions would be nice!
COM has a feature that's entirely missing in .NET. A COM class can specify whether it is thread-safe or not. It does so with a key in the registry named ThreadingModel. Just like most .NET classes, the vast majority of COM classes are not thread-safe so they specify "Apartment". Which is a somewhat obscure term that implies "only call me from the thread on which I was created". Which automatically provides thread-safety.
To make that work, a thread that creates COM objects has to indicate what kind of support it is willing to provide for COM classes that are not thread safe. An STA thread is a safe home. Requirement is that the thread pumps a message loop, like any UI thread does. The message loop is the mechanism by which COM marshals a call from a worker thread to the thread that created the object. A thread that joins the MTA specifically says it does not provide support.
COM has to do something about MTA threads, they are not suitable for COM objects that are not thread safe. It creates a new thread, an STA thread to give the COM object a safe home. That's quite inefficient, every method call has to be marshaled. And risky, a COM class may still be thread-unsafe if its objects share state internally.
So what's happening in your Winforms case is that you created all the objects on the main thread, which is an STA. And make calls from parallel worker threads, those calls all get marshaled and serialized back to the STA thread. Inevitably, they execute one-by-one and you get no concurrency.
In your Console case, you created them on an MTA thread. So COM is forced to create threads for each object. The method calls on your worker threads are still marshaled, but now to multiple threads. So now you do get concurrency, at the cost of significant overhead, a bunch of extra threads. And the risk of failure when the server shares state internally.
Make the Winforms case the same as the Console case by creating the COM objects on a worker thread. Do test it very thoroughly.
STA and MTA are both "threading models" for COM/ActiveX, dating back to the mid 1990's.
Here's a good link:
http://msdn.microsoft.com/en-us/library/ms809971.aspx
STA:
A process has one single-threaded apartment (STA) for each thread that
called CoInitialize. Each of these apartments, in turn, may have zero
or more COM objects associated with them. As the name implies,
however, only one specific thread (the thread that created the
apartment by calling CoInitialize) may directly access the objects
within the apartment
MTA:
Although multi-threaded apartments, sometimes called free-threaded
apartments, are a much simpler model, they are more difficult to
develop for because the developer must implement the thread
synchronization for the objects, a decidedly nontrivial task. On the
positive side, removing an STA's synchronization mechanism gives the
developer much finer control over the use of thread synchronization.
They can apply it where it is actually needed rather than taking the
very conservative approach of STAs, which synchronize access to the
entire apartment.
One issue is choosing the best threading model for your component (the default is STA, IIRC). Another issue is what the runtime will do if you need to marshal data between your component and a component that uses a different threading model. The link above discusses both.
The full error I get is as follows:
The CLR has been unable to transition from COM context 0x1a8188 to COM context 0x1a8018 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.
Any idea what this means? And how is should be solved? I tried searching on Google, but couldn't find anything of consequence, i.e. relating to my specific scenario.
Edit:
The Specific scenario:
1. Integrating WPF into WinForms
2. The WPF screens are written for a plugin dll, which is dynamically loaded into the main application.
Thanks
Hasanain
This means that you created an object on thread A, then tried to use it on thread B, but thread A was really busy and the COM object requires that it be running on thread A. Try to see why thread A is busy.
I am new to WPF, and in every tutorial I read, they either have a [System.STAThread] attribute applied to their Main method, or they tell the reader to do that.
Is this attribute really "required"? And if so, why?
This is more a Windows requirement than a WPF one, and goes back to the original design of Windows forms and controls, from before .NET.
STAThread refers to "Single-Threaded Apartments" which refers to the threading model used by the current (main) thread. The threading model in use dictates how other .NET and COM applications will talk to your application (and inherently, its threads). The single-threaded application model requires that no single object "live in" more than one STA thread at a time, verses the MTA thread model; and allows for the passing of pointers to data across apartments only via marshalling-as-object.
Basically, with the [STAThread] declaration, other applications will know what your thread's policy is when sending you data. The STA model is the most common threading model for Windows threads/applications; but you'll sometimes come across certain code that won't run if called from an STA-modeled thread, because it's designed to send/receive data across thread boundaries in ways that don't comply with the STA restrictions. Knowing beforehand what the apartment model of a given thread allows the IDE to catch these exceptions at compile-time instead of getting nasty access violation errors when you attempt to use an object across thread boundaries during runtime.
You can read about STA and MTA threads from the MSDN article at: http://msdn.microsoft.com/en-us/library/ms680112(VS.85).aspx
Note that even normal .NET applications (from before WPF) required the [STAThread] declaration atop of the main().
There's an excellent answer for this in this blog entry.
Quoting from the blog:
When the STAThreadAttribute is
applied, it changes the apartment
state of the current thread to be
single threaded. Without getting into
a huge discussion about COM and
threading, this attribute ensures the
communication mechanism between the
current thread and other threads that
may want to talk to it via COM. When
you're using Windows Forms, depending
on the feature you're using, it may be
using COM interop in order to
communicate with operating system
components. Good examples of this are
the Clipboard and the File Dialogs.
Windows Forms is not supported within
a MTA or free threaded apartment.
Applications using Windows Forms
should always declare the apartment
style they're using, as some other
component could initialize the
apartment state of thread improperly.