Dot-Net

AppDomain.GetCurrentThreadID vs Thread.ManagedThreadID 用於 Windows API 呼叫?

  • November 6, 2015

我正在嘗試創建一個掛鉤來監視滑鼠游標的目前位置。沒什麼重要的,我只需要在界面設計期間計算一些像素,並想學習如何創建一個鉤子,所以我決定走一條艱難的路,而不是理智的路。

我找到了聲明以下函式的範常式式碼:

<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 執行緒上執行它,您可以假設此標識符具有合理的穩定性水平。

引用自:https://stackoverflow.com/questions/772354