STA definition: "single thread affinity" or "single threaded flat"; and how they relate
I am working with WPF and reading STA stuff. Two questions:
1) STA is defined as standing for both "single-threaded" and "single-threaded apartment" by different entries. It says about the former: https://msdn.microsoft.com/en-us/library/ms750441(v=vs.110).aspx It speaks about the latter: https://msdn.microsoft.com/en-us/ library / ms742522 (v = vs.110) .aspx
What is it, or can STA refer to any of these related concepts?
2) Is it correct to describe their relationship as: Single-threaded flat is a model used by various Windows components, thread affinity is a characteristic of this model?
Thank.
source to share
STA stands for "One-Thread Apartment". This is a COM concept that has nothing to do with WPF. WPF designers learned of bugs in .NET 1.x, many programmers wrote programs that violated thread safety requirements and made their programs very time-consuming. Therefore, they added more runtime checks to the .NET framework code to help them get out of trouble.
While this is a pure COM concept, the underlying principle is quite universal. By declaring an STA thread, you are promising that the code you write will behave well. You write well thought out code by running a dispatcher loop (Application.Run) and never block code that runs on a thread. Breaking this promise causes a dead end.
The vast majority of .NET classes, as well as most of the code you write yourself, are unsafe. There are two main ways to make this code thread safe. The first is the approach you take on a class like List <>, which you put blocking statements in your code to ensure that the List object can only be accessed one thread at a time.
This usually works fine, but the more complex the class becomes, the harder it is to figure out where to put the lock statements and the more likely such locks are to cause a deadlock. The only other option you need to keep your code threaded is to ever make method calls on the same thread. All WPF components are like this, you have to call Dispatcher.Begin / Invoke () from the worker thread to set their properties or call their methods. Now you can say that the object has a thread-affinity, it is only accessible from the thread that created it.
The WPF designers wanted to add these runtime checks to mislead the programmer that they are using a WPF component. The component can only work with a thread called Application.Run (), so Dispatcher.Begin / Invoke () will work. The problem is that they cannot determine if a thread will respond to Application.Run (). This often happens later. A promise is needed.
So they borrowed the COM promise, the state of the apartment in the thread is always given and gives a decent hint of how it will behave. No guarantee, just a decent hint. The main thread of a WPF application is almost always appropriate, it is STA thanks to the [STAThread] attribute on the Main () entry point, and the project template ensures that it calls Application.Run (). And the Task thread or thread-pool is in the MTA and will never call Application.Run (), so this is a very hostile place for a WPF component.
The exception they throw does not give the programmer a problem. Note how you can suppress this exception very easily. All you have to do is call Thread.SetApartmentState () to fulfill the promise. But of course you are now flying without a safety net, WPF can no longer tell you that you are doing it wrong, now you completely need to write the code correctly. You should call Application.Run () even if you usually don't want to.
source to share
STAThreadAttribute
tells the .NET VM to set up the original COM thread of the apartment to a single threaded apartment (STA).
1) This is what STA, A means for an apartment, not for proximity.
The main problem here is dealing with external COM components, usually GUI controls such as a control WebBrowser
that instantiates an embedded IE component that must support STA.
2) Yes, STA implies thread merging, which is a requirement for Win32 windows and window messages in general.
In practice, you can either mark Main()
with [STAThread]
or create a new thread, set it flat , and then start it while you start the message loop later, for example Application.Run()
or WaitOne
on WaitHandle
, as it will use CoWaitForMultipleHandles
.
So, here are the implications of an attribute STAThread
or starting a thread configured for an STA:
-
The virtual machine will call
CoInitializeEx
withCOINIT_APARTMENTTHREADED
-
You must run a message loop to provide interconnect calls to apartment objects.
-
Even if you don't expect cross-network calls, you should still run a message loop because STA COM components may require one, usually due to the use of GUI APIs, directly or indirectly, for example. shell functions
-
WaitOne
andWaitAny
will use pending message forwarding, for example,CoWaitForMultipleHandles
instead of a simpleWaitForSingleObjectEx
/WaitForMultipleObjectsEx
-
WaitAll
not supported because the underlying API will wait on all handles and message queues, there is no passive way to wait on all handle set or message queues
source to share
- STA stands for "single threaded apartment" - the COM model for handling multi-threaded access to a COM object. The interconnection of threads is a consequence of this model - when one thread has entered an apartment STA, no other thread can enter that apartment. And the owner of the thread of the apartment cannot be changed.
- It is correct to describe their relationship as: Single-threaded apartment is the model used to handle multi-threaded access to a COM object , the affinity of the thread is the implication of this model.
source to share