你能解釋一下STA和MTA嗎?

你能用本身的話解釋STA和MTA嗎? 安全

什麼是公寓線程,它們只與COM有關嗎? 若是是這樣,爲何? 多線程


#1樓

每一個承載COM或OLE控件的EXE都定義它的公寓狀態。 公寓狀態默認爲STA(而且對於大多數程序應該是STA)。 併發

STA - 必要時全部OLE控件必須位於STA中。 STA意味着必須始終在UI線程上操做COM對象,而且不能將其傳遞給其餘線程(很是相似於MFC中的任何UI元素)。 可是,您的程序仍然能夠有許多線程。 學習

MTA - 您能夠在程序中的任何線程上操做COM對象。 spa


#2樓

COM線程模型稱爲「單元」模型,其中初始化COM對象的執行上下文與單個線程(單線程單元)或多個線程(多線程單元)相關聯。 在此模型中,COM對象一旦在公寓中初始化,就會在其運行時間內成爲該公寓的一部分。 線程

STA模型用於非線程安全的COM對象。 這意味着他們不會處理本身的同步。 這個的常見用途是UI組件。 所以,若是另外一個線程須要與對象交互(例如按下表單中的按鈕),則將消息編組到STA線程上。 窗口造成消息泵系統就是一個例子。 設計

若是COM對象能夠處理本身的同步,則可使用MTA模型,其中容許多個線程與對象交互而無需編組調用。 code


#3樓

STA(單線程單元)基本上是一次只有一個線程與您的代碼交互的概念。 經過Windows消息(使用不可見的)窗口對您公寓的呼叫進行封送。 這容許調用排隊並等待操做完成。 對象

MTA(多線程公寓)是許多線程能夠同時運行的地方,做爲開發人員負責處理線程安全性的責任在你身上。 進程

關於COM中的線程模型還有不少東西要學習,但若是你沒法理解它們是什麼,那麼我會說理解STA是什麼以及它是如何工做的將是最好的起點,由於大多數COM對象都是STA的。

Apartment Threads,若是一個線程與它正在使用的對象住在同一個公寓,那麼它就是一個公寓線程。 我認爲這只是一個COM概念,由於它只是一種談論它們與之交互的對象和線程的方式......


#4樓

這徹底取決於如何處理對象的調用,以及他們須要多少保護。 COM對象能夠要求運行時保護它們不被多個線程同時調用; 那些不能夠從不一樣線程同時調用,所以他們必須保護本身的數據。

此外,若是從用戶界面線程進行調用,運行時還必須阻止COM對象調用阻止用戶界面。

公寓是物品居住的地方,它們包含一個或多個線程。 公寓定義了撥打電話時會發生什麼。 對公寓中的對象的調用將在該公寓中的任何線程上接收和處理,除了已經在正確的公寓中的線程的調用由其自身處理(即直接調用該對象)。

線程能夠是單線程公寓(在這種狀況下,它們是該公寓中惟一的線程)或多線程公寓。 它們指定線程爲該線程初始化COM的時間。

STA主要用於與用戶界面兼容,用戶界面與特定線程相關聯。 STA經過接收到隱藏窗口的窗口消息來接收處理呼叫的通知; 當它進行出站呼叫時,它會啓動模態消息循環以防止處理其餘窗口消息。 您能夠指定要調用的消息過濾器,以便您的應用程序能夠響應其餘消息。

相比之下,全部MTA線程共享該進程的單個MTA。 若是沒有可用的線程,COM能夠啓動一個新的工做線程來處理傳入的調用,直到池限制。 進行出站呼叫的線程只是阻止。

爲簡單起見,咱們只考慮在DLL中實現的對象,經過爲其類的鍵設置ThreadingModel值,在註冊表中公佈它們支持的內容。 有四種選擇:

  • 主線程( ThreadingModel值不存在)。 該對象是在主機的主UI線程上建立的,而且全部調用都被編組到該線程。 只能在該線程上調用類工廠。
  • Apartment 。 這代表該類能夠在任何單線程模式線程上運行。 若是建立它的線程是STA線程,則該對象將在該線程上運行,不然將在主STA中建立 - 若是不存在主STA,則將爲其建立STA線程。 (這意味着建立Apartment對象的MTA線程將編組全部對不一樣線程的調用。)類工廠能夠由多個STA線程同時調用,所以它必須保護其內部數據不受此影響。
  • Free 這表示設計爲在MTA中運行的類。 即便由STA線程建立,它也將始終加載到MTA中,這再次意味着STA線程的調用將被編組。 這是由於Free對象一般是在能夠阻止的狀況下編寫的。
  • Both 。 這些類是靈活的,能夠在任何建立它們的公寓中加載。 必須編寫它們以知足兩組要求,可是:它們必須保護它們的內部狀態免受併發調用的影響,以防它們被加載到MTA中,可是若是它們被加載到STA中則不能阻塞。

從.NET Framework,基本上只在建立UI的任何線程上使用[STAThread] 。 工做線程應該使用MTA,除非他們打算使用帶Apartment標記的COM組件,在這種狀況下,若是從多個線程調用相同的組件,則使用STA以免編組開銷和可伸縮性問題(由於每一個線程都必須等待對於組件反過來)。 若是你爲每一個線程使用一個單獨的COM對象,不管組件是在STA仍是MTA中,它都會更加容易。


#5樓

調用COM對象dll的代碼(例如,讀取專有數據文件)可能在用戶界面中正常工做,但在服務中神祕地掛起。 緣由是.Net 2.0用戶界面假設STA(線程安全),而服務假定MTA(在此以前,服務假設STA)。必須爲服務中的每一個COM調用建立STA線程可能會增長顯着的開銷。

相關文章
相關標籤/搜索