分享方式:


Windows 中的受控與非受控執行緒處理

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

當 Unmanaged 執行緒透過類似 COM 可呼叫包裝函式來進入執行階段時,系統會檢查此執行緒的執行緒本機存放區,以尋找內部 Managed Thread 物件。 如果找到一個物件,表示執行階段已感知此執行緒。 但是,如果找不到任何 Thread 物件,執行階段會建置新物件並安裝到此執行緒的執行緒本機存放區中。

在 Managed 執行緒中, Thread.GetHashCode 是穩定的 Managed 執行緒識別。 在執行緒的存留期間,此值不會與其他任何執行緒的值相衝突,不論您是從哪一個應用程式定義域取得此值。

從 Win32 執行緒處理對應至受控執行緒處理

下表將 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

受控執行緒與 COM Apartment

可標記 Managed 執行緒,以表示它將裝載單一執行緒多執行緒 Apartment。 (如需 COM 執行緒架構的詳細資訊,請參閱處理序、執行緒和 Apartment \(英文\))。GetApartmentState 類別的 SetApartmentStateTrySetApartmentStateThread 方法會傳回並指派執行緒的 Apartment 狀態。 如果尚未設定此狀態,則 GetApartmentState 會傳回 ApartmentState.Unknown

只有在執行緒處於 ThreadState.Unstarted 狀態時,才能設定此屬性;每個執行緒只能設定此屬性一次。

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

重要

對於應用程式啟動程式碼而言,控制 Apartment 狀態的唯一方式是將 MTAThreadAttributeSTAThreadAttribute 套用至進入點程序。

公開至 COM 之受控物件的行為會像是已彙總無限制執行緒封送處理器。 換句話說,您可以使用無限制執行緒方式從任何 COM Apartment 呼叫 Managed 物件。 只有衍生自 ServicedComponentStandardOleMarshalObject 的 Managed 物件才不會表現出無限制執行緒行為。

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

當 Managed 程式碼呼叫 COM 物件時,一律會遵循 COM 規則。 換句話說,程式碼會依照 OLE32 指示,透過 COM Apartment Proxy 和 COM+ 1.0 內容包裝函式來呼叫。

封鎖問題

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

執行緒與 Fiber

.NET 執行緒模式不支援 Fiber。 您不應該呼叫至使用 Fiber 實作的任何非受控函式。 此類呼叫可能會導致 .NET 執行階段當掉。

另請參閱