關於[STAThread]

首先,我們瞭解一下[STAThread]語句的含義。

[STAThread]是指,single thread apartment thread - 單一套間線程

 

關於進程、線程、MTU、STU、COM之間的關係如下圖所示:


網絡上比較生動的解釋是這樣的:

進程相當於一個小城鎮。

線程相當於這個城鎮裏的居民。

STA(單線程套間)相當於居民房,是私有的。

MTA(多線程套間)相當於旅館,是公用的。

Com對象相當於居民房或旅館裏的物品。

 

接下去就好理解了,一個小城鎮(進程)裏可以有很多很多的(居民)線程,這個城鎮(進程)只有一間旅館(MTA),但可以有很多很多的居民房(STA)。

只有居民(線程)進入了房間(居民房或旅館,STA或MTA)以後才能使用該房間裏的物品(COM對象)。

居民房(STA)裏的物品(COM對象)只能供這間房子的主人(創建該STA的線程)使用,其它居民(線程)不能訪問。

同樣,只有入住到旅館(MTA)裏的居民(線程,可以有多個)纔可以訪問到旅館(MTA)裏的物品(com對象),但因爲是公用的,所以要合理的分配(同步)才能不會產生混亂。

 

線程是程序執行的最小單元。

STA (single threadapartment,單一線程套間),就是在COM庫初始化的時候創建一個內存結構,然後讓它和調用CoInitialize的線程相關聯。這個內存結構針對每個線程都會有一個。支持STACOM對象只能在創建它的線程裏被使用,其它線程如果再創建它就會失敗。

 

MTA(multi threadapartment,多線程套間),COM庫在進程中創建一個內存結構,這個內存結構在整個進程中只能有一個,然後讓它和調用CoInitializeEx的線程相關聯。支持MTACOM對象可以在任意線程裏被使用。多有針對它的調用都會被封裝成爲消息。

其實STA和MTA是COM規定的一套線程模型,用於保障多線程情況下你的組件代碼的同步。比如說有一個COM對象它內部有一個靜態變量   gHello,那麼這個對象無論生成多少實例對於gHello在內存中只能有一份,那麼如果有兩個不同的實例在兩個線程裏面同時去讀寫它,就有可能出錯,所以就要就要有種機制進行同步保護,STA或者MTA就是這種機制。

 

他們是.NET支持的兩種線程模式。

Apartment是邏輯上的概念,STA的apartment只包含一個線程(thread),相應的,MTA可以包含多個線程。從上面的描述可以看出:一個進程只有一個MTA,可以有多個STA;STA中的com只能由自身線程調用,MTA中的com可以由裏面所有的線程調用。

STA 和MTA之間最大的區別是MTA可以在同一個apartment中使用所有的共享資源併發執行多個線程。而多個STA雖然可以共享數據,但是不能併發執行線程,存在性能問題。

好了,現在知道他們之間的關係,那麼,程序是如何使用STA\MTA的呢?在何種情況下會使用呢?使用了對程序有什麼影響呢?下面來一一解答。

 

STA用在程序的入口方法上,來指定當前線程的套間狀態(apartmentState)是STA。

 

示例:

我現在想在一個windowsform的程序中實現從某個word文檔複製圖片並保存的方案。

具體是:打開word文檔,將圖片信息複製到粘貼板中,然後從粘貼板中取得圖片信息,再保存到本地目錄中。

說明:(本來是放在代碼下面的,無奈POST之後就被代碼擋住不顯示了)

如果在某個按鈕的事件中,直接調用該方法,那麼界面將變得沒有響應。所以我們需要考慮使用多線程來解決這個問題。Threadt = new Thread(new TheardStart(CopyImages); t.Start();

如果是這樣,則程序會發生錯誤.。要麼顯示出現異常,要麼沒異常但是Clipboard爲空,取不到任何數據!爲什麼呢?

因爲Word.Application是Automation並且STA-Based,不能在沒有指定ThreadApartment的線程中被調用。所以導致了各種錯誤,所以需要在t.Start();前面加上t.Apartment= ApartmentState.STA;這樣就完全正常了。

對於MTA的多線程我們就見的比較多了,不再舉例了。

另外一點不明白,我監視任務管理器發現,我在執行Threadt = new Thread(new TheardStart(CopyImages);t.Apartment = ApartmentState.STA;t.Start();之後該程序的進程中線程數從3個增加到6個,如果創建的是MTA的線程則只增加1。我的理解是STA線程爲需要維護內部隱藏的窗口類和消息隊列而增加的。

 

發佈了34 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章