AppDomain.GetCurrentThreadID vs Thread.ManagedThreadID 用於 Windows API 呼叫?
我正在嘗試創建一個掛鉤來監視滑鼠游標的目前位置。沒什麼重要的,我只需要在界面設計期間計算一些像素,並想學習如何創建一個鉤子,所以我決定走一條艱難的路,而不是理智的路。
我找到了聲明以下函式的範常式式碼:
<DllImport("User32.dll", CharSet:=CharSet.Auto, _ CallingConvention:=CallingConvention.StdCall)> _ Public Overloads Shared Function SetWindowsHookEx _ (ByVal idHook As Integer, ByVal HookProc As CallBack, _ ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer End Function呼叫該函式時,使用以下程式碼:
hHook = SetWindowsHookEx(WH_MOUSE, _ hookproc, _ IntPtr.Zero, _ AppDomain.GetCurrentThreadId())但是 Appdomain.GetCurrentThreadID 會生成警告:“‘Public Shared Function GetCurrentThreadId() As Integer’ 已過時:‘AppDomain.GetCurrentThreadId 已被棄用,因為當託管執行緒在纖程(又名輕量級執行緒)上執行時,它不提供穩定的 Id。要獲得託管執行緒的穩定標識符,請使用 Thread 上的 ManagedThreadId 屬性。”
我嘗試過使用 ManagedThreadID,但這不起作用。返回的執行緒 ID 似乎是執行緒的邏輯執行緒 ID,因為它在 .net 執行時中執行,而不是 Win32 執行緒標識符。
使用 AppDomain.GetCurrentThreadID 呼叫該函式是可行的,但我真的很想為我的執行緒提供一個“穩定標識符”。
有人可以向我解釋是否可以在這種情況下使用 ManagedThreadID(我假設不是),如果沒有,我需要避免的事情是為了阻止 AppDomain.CurrentThreadID 變得“不穩定”?
乾杯
在此上下文中無法使用 ManagedThreadId。這是一個完全託管的概念,在原生世界中沒有真正的代表。因此,它對您傳遞給它的 API 沒有任何意義。
ManagedThreadId 存在的原因是本機執行緒和託管執行緒之間不一定存在 1-1 映射。只要本機執行緒與其要替換的執行緒兼容,CLR 就可以自由地使用多個本機執行緒來執行單個託管執行緒。例如,它不能在不同的 COM 公寓中。
在某些方面,你有點卡在這裡。AFAIK,沒有辦法 100% 保證對於給定的託管執行緒,您將擁有相同的本機執行緒。但是,如果您正在執行 WinForms 或 WPF 應用程序並且對本機程式碼的呼叫發生在 UI 執行緒上,則您可以獲得非常高水平的保證。原因是這兩個 UI 框架都存在於 STA 公寓中,這使得 CLR 很難(如果可能的話)從您的下方切換出來。
簡短版本:如果您在 WinForms 或 WPF 應用程序中並在 UI 執行緒上執行它,您可以假設此標識符具有合理的穩定性水平。