我正在尝试创建一个钩子来监视鼠标光标的当前位置。没什么重要的,我只需要在界面设计期间计算一些像素,并想学习如何创建钩子,所以我决定采用一种困难的方法,而不是理智的方法。

我找到了声明以下功能的示例代码:

 <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。要获取托管线程的稳定标识符,请使用线程上的ManagedThreadId属性。”

我尝试使用ManagedThreadID,但这不起作用。返回的线程ID似乎是该线程的逻辑线程ID,因为它在.net运行时中运行,而不是Win32线程标识符。

调用函数ith AppDomain.GetCurrentThreadID可以,但是我真的很想为我的线程添加一个“稳定标识符”。

有人可以向我解释在这种情况下是否可以使用ManagedThreadID(我认为不是),如果不能,那么我需要避免一些事情以阻止AppDomain.CurrentThreadID变得“不稳定”?

干杯

最佳答案

在这种情况下不能使用ManagedThreadId。这是一个完全管理的概念,在本地世界中没有真实的代表。因此,将您传递给的API毫无意义。

存在ManagedThreadId的原因是因为本机线程与托管线程之间不一定存在1-1映射。只要本地线程与其要替换的本地线程兼容,CLR就可以免费使用多个本地线程来运行单个托管线程。例如,它不能位于其他COM公寓中。

从某些方面来说,您这里有些卡住。 AFAIK,无法100%保证给定托管线程具有相同的本机线程。尽管例如,如果您正在运行WinForms或WPF应用程序,并且对本机代码的调用发生在UI线程上,则可以实现很高的保证。原因是这两个UI框架都生活在STA公寓中,这使得CLR很难(甚至可能)从您身下切换。

简短版:如果您在WinForms或WPF应用程序中并在UI线程上运行它,则可以假定此标识符具有合理的稳定性。

关于.net - Windows API调用的AppDomain.GetCurrentThreadID与Thread.ManagedThreadID?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/772354/

10-13 06:57