共用方式為


Microsoft Windows 中的 Managed 和 Unmanaged 執行緒處理

更新:2007 年 11 月

所有執行緒的管理全都透過 Thread 類別進行,包括由 Common Language Runtime 建立的執行緒以及在 Runtime 之外建立,但進入 Managed 環境執行程式碼的執行緒。Runtime 會監視在其處理序中所有曾在 Managed 執行環境中執行程式碼的執行緒。它不會追蹤任何其他執行緒。執行緒可透過 COM Interop (因為執行階段會將 Managed 物件當做 COM 物件公開給 Unmanaged 外界)、COM DllGetClassObject() 函式和平台叫用 (Invoke) 進入 Managed 執行環境。

當 Unmanaged 執行緒透過類似 COM 可呼叫包裝函式進入執行階段時,系統會檢查這個執行緒的執行緒區域存放區,以尋找內部 Managed Thread 物件。如果找到的話,Runtime 就知道這個執行緒。不過,如果系統找不到執行緒,Runtime 會建置新的 Thread 物件並將它安裝在這個執行緒的執行緒本機存放區中。

在 Managed 執行緒處理中,Thread.GetHashCode 是穩定的 Managed 執行緒識別。就執行緒的存留期 (Lifetime) 而言,無論您是從哪一個應用程式定義域獲得這個值,執行緒的存留期都不會與任何其他執行緒發生衝突。

注意事項:

作業系統 ThreadId 與 Managed 執行緒之間沒有固定的關係,因為 Unmanaged 主應用程式可控制 Managed 和 Unmanaged 執行緒之間的關係。具體而言,精密的主機可使用 Fiber API 以依據同一作業系統執行緒來排程許多 Managed 執行緒,或是在不同作業系統執行緒之間移動 Managed 執行緒。

從 Win32 執行緒處理對應至 Managed 執行緒處理

下列表格將 Win32 執行緒處理項目對應至它們近似的執行階段對等項。請注意,此對應並不代表功能完全一樣。例如,TerminateThread 不執行 finally 子句或釋放資源,並且無法防止。然而,Thread.Abort 會執行所有的復原程式碼、回收所有資源,並且可使用 ResetAbort 加以拒絕。在設想功能之前,一定要仔細閱讀文件。

在 Win32 中

在 Common Language Runtime 中

CreateThread

ThreadThreadStart 的組合

TerminateThread

Thread.Abort

SuspendThread

Thread.Suspend

ResumeThread

Thread.Resume

Sleep

Thread.Sleep

執行緒控制代碼上的 WaitForSingleObject

Thread.Join

ExitThread

沒有對等用法

GetCurrentThread

Thread.CurrentThread

SetThreadPriority

Thread.Priority

沒有對等用法

Thread.Name

沒有對等用法

Thread.IsBackground

近似 CoInitializeEx (OLE32.DLL)

Thread.ApartmentState

Managed 執行緒和 COM Apartment

可標記 Managed 執行緒以指出它將裝載單一執行緒或多執行緒 Apartment。Thread 類別的 GetApartmentStateSetApartmentStateTrySetApartmentState 方法會傳回並指派執行緒的 Apartment 狀態。如果尚未設定此狀態,則 GetApartmentState 會傳回 ApartmentState.Unknown

注意事項:

在 .NET Framework 1.0 和 1.1 版中,ApartmentState 屬性是用來取得及設定 Apartment 狀態。

只有當執行緒是處於 ThreadState.Unstarted 狀態時,才能設定此屬性;它只能針對執行緒設定一次。

如果在執行緒啟動之前就設定了 Apartment 狀態,則執行緒會初始化為多執行緒 Apartment (MTA)。受到 ThreadPool 控制的完成項執行緒及所有執行緒都是 MTA。

重要事項:

對於應用程式啟始程式碼 (Startup Code) 而言,控制 Apartment 狀態的唯一方法就是將 MTAThreadAttributeSTAThreadAttribute 套用到進入點程序。在 .NET Framework 1.0 和 1.1 版中,ApartmentState 屬性可設定為程式碼的第一行;而在 .NET Framework 2.0 版中不允許這樣的處理。

公開至 COM 的 Managed 物件看起來像是已彙總無限制執行緒封送處理器 (Free Threaded Marshaler)。換言之,可以無限制執行緒方式從任何 COM Apartment 呼叫 Managed 物件。只有衍生自 ServicedComponent 的 Managed 物件才不會表現出無限制執行緒行為。

在 Managed 世界中,除非您使用內容及內容繫結 Managed 執行個體,否則不支援 SynchronizationAttribute。如果您正在使用 EnterpriseServices,則您的物件必須衍生自 ServicedComponent (其本身係衍生自 ContextBoundObject)。

當 Managed 程式碼呼叫 COM 物件時,一定會遵循 COM 規則。換言之,它會按照 OLE32 的指示呼叫 COM Apartment Proxy 和 COM+ 1.0 內容包裝函式。

封鎖問題

如果執行緒對作業系統發出 Unmanaged 呼叫,而此呼叫在 Unmanaged 程式碼中封鎖了執行緒,則執行階段將不會針對 Thread.InterruptThread.Abort 取得其控制權。如果是 Thread.Abort 的情況,則執行階段會為 Abort 標記執行緒,並在它重新進入 Managed 程式碼時取得其控制權。建議您使用 Managed 封鎖,而不要使用 Unmanaged 封鎖。WaitHandle.WaitOneWaitHandle.WaitAnyWaitHandle.WaitAllMonitor.EnterMonitor.TryEnterThread.JoinGC.WaitForPendingFinalizers 等等,對於 Thread.InterruptThread.Abort 都會有回應。此外,如果執行緒位在單一執行緒 Apartment 中,則當執行緒被封鎖時,所有這些 Managed 封鎖作業都會正確提取 Apartment 中的訊息。

請參閱

參考

Thread.ApartmentState

Threadstate 列舉型別

ServicedComponent

Thread

Monitor