[STAThread]的含義

pamxy發表於2013-09-10

轉自:http://www.cnblogs.com/huashanlin/archive/2007/07/07/809305.html

[STAThread]
STAThread:Single     Thread     Apartment Thread.(單一執行緒單元執行緒)
[]是用來表示Attributes;

[STAThread]
是一種執行緒模型,用在程式的入口方法上(在C#和VB.NET裡是Main()方法),來指定當前執行緒的ApartmentState 是STA。用在其他方法上不產生影響。在aspx頁面上可以使用AspCompat = "true" 來達到同樣的效果。這個屬性只在  Com  Interop  有用,如果全部是  managed  code  則無用。簡單的說法:[STAThread]指示應用程式的預設執行緒模型是單執行緒單元 (STA)。啟動執行緒模型可設定為單執行緒單元或多執行緒單元。如果未對其進行設定,則該執行緒不被初始化。也就是說如果你用的.NET Framework,並且沒有使用COM Interop,一般不需要這個Attribute。其它的還有MTA(多執行緒套間)、Free  Thread(自由執行緒)。 

[STAThread] attribute指示應用程式的 COM 執行緒模型是單執行緒單元。
而於此對應的多執行緒單元則是 [MTAThread] (多執行緒單元執行緒)

COM 執行緒模型只適用於使用 COM interop 的應用程式。如果將此屬性應用到不使用 COM interop 的應用程式,將沒有任何效果。

COM 執行緒模型可設定為單執行緒單元或多執行緒單元。如果應用程式執行緒實際呼叫了 COM 元件,則僅為 COM interop 初始化該執行緒。如果沒有使用 COM interop,則不初始化該執行緒。

以下是找到的一個資料介紹:
Q. When I create a c# project from scratch in VS.NET, the generated code always have a [STAThread] attribute above the main routine. What does the STAThread attribute really do? Can I change it to MTAThread instead? I have searched website and books, no one seems to explain this well.

Asked by anon. Answered by the Wonk on February 17, 2003

A.

The STAThreadAttribute marks a thread to use the Single-Threaded COM Apartment if COM is needed. By default, .NET won't initialize COM at all. It's only when COM is needed, like when a COM object or COM Control is created or when drag 'n' drop is needed, that COM is initialized. When that happens, .NET calls the underlying CoInitializeEx function, which takes a flag indicating whether to join the thread to a multi-threaded or single-threaded apartment.

A multi-threaded apartment (MTA) in COM is more efficient, since any of a number of RPC threads from a pool can be used to handle a request. However, an object on the MTA thread needs to protect itself from multiple threads accessing it at the same time, so that efficiency comes at a cost.

The single-thread apartment (STA) in COM is inherently single-threaded and therefore no additional thread synchronization is needed. The STA is implemented using the thread's Windows message queue, which is how requests to objects on an STA are serialized. Because of how the STA thread is implemented, calls to objects on that thread are serialized with Windows message handling on that thread, making sure that everything, both the COM objects and the underlying windowing objects, e.g. HWNDs, are all synchronized. This is necessary for UI-oriented COM objects, like controls and drag 'n' drop, which must also be synchronized together with the UI.

When COM is needed .NET will call CoInitializeEx, picking the MTA by default because it's more efficient. However, to get the synchronization needed for controls, windows and drag 'n' drop, you need to mark a thread's entry point with the STAThreadAttribute to let .NET know to initialize the UI thread on the STA. All of the VS.NET project templates put that attribute in to make sure you don't forget:
大致意思是:由於很多COM在.NET環境下如果使用多執行緒的話,會導致引用的COM不能正常執行,而如果不宣告程式為STAThread的話,.NET就會自動使用多執行緒來提高效率,這樣就會導致不可預知的後果。




以下引用另一同輩的發言:http://blog.csdn.net/qilang/archive/2006/06/06/775605.aspx
STA不是單執行緒的意思.英文為single threaded apartment.是一種套間(或譯為公寓)執行緒模式.

sta thread並不表明應用程式的型別,和應用程式不搭界,恰相反,一個應用程式可以有多個執行緒.每個執行緒也可以有多個元件或物件.以前win16位系統的元件執行緒模式才真正是單執行緒.這是一種被淘汰了的模式.
執行緒模式用於處理元件在多執行緒的環境裡並行與並互的方式.比如套間執行緒(STAThread)模式中介面跨執行緒傳遞必須被排程(Marshal),不排程直傳肯定會失敗!而MTA或FreeThread模式中的介面可以不經排程直接傳遞.
這種排程在特定的環境中非常影響效能(可有幾百倍之差).如VB裡只支援STAThread模式.FreeThread模式的元件會在裡面表現成和跨程式一樣慢!
執行緒模式是微軟的COM基礎中的極其重要的概念.一定要吃透!
我對.net真是一竅不通(沒空去弄,對不起微軟去年的獎賞).但我可以肯定,C#中的[STAThread]屬性是應用程式的套間初始化程式碼.可以直接理解成SDK裡的
CoInitialize(NULL); 
初始一個STA套間實際上是相當於開了一個訊息視窗,所有呼叫經此視窗過程排程到元件內.
同理[MTAThread](不知有沒有這個屬性,自已去查)
可以理解成
CoInitializeEx(NULL,COINIT_MULTITHREADED )
這經常是一個對初入com大門的人來說,有一定難度但必須過的一道關.


相關文章