例如,在c#中调试线程时,你可以看到每个线程的ID。
我无法找到一种方法以编程方式获得相同的线程。我甚至无法获得当前线程的ID(在thread . currentthread的属性中)。
所以,我想知道Visual Studio如何获得线程的id,是否有一种方法来获得id 2345的线程句柄,例如?
例如,在c#中调试线程时,你可以看到每个线程的ID。
我无法找到一种方法以编程方式获得相同的线程。我甚至无法获得当前线程的ID(在thread . currentthread的属性中)。
所以,我想知道Visual Studio如何获得线程的id,是否有一种方法来获得id 2345的线程句柄,例如?
当前回答
对于那些想要入侵的人:
public static int GetNativeThreadId(Thread thread)
{
var f = typeof(Thread).GetField("DONT_USE_InternalThread",
BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
var pInternalThread = (IntPtr)f.GetValue(thread);
var nativeId = Marshal.ReadInt32(pInternalThread, (IntPtr.Size == 8) ? 548 : 348); // found by analyzing the memory
return nativeId;
}
其他回答
查找当前线程Id使用- ' thread . currentthread . managedthreadid '。 但在这种情况下,你可能需要当前的win32线程id -使用pInvoke函数来获得它:
[DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
public static extern Int32 GetCurrentWin32ThreadId();
首先,您需要保存托管线程id和win32线程id连接—使用字典将win32 id映射到托管线程。
然后使用process . getcurrentprocess()遍历进程的线程,通过线程的id找到线程。线程,并找到具有该id的线程:
foreach (ProcessThread thread in Process.GetCurrentProcess().Threads)
{
var managedThread = win32ToManagedThread[thread.id];
if((managedThread.ManagedThreadId == threadId)
{
return managedThread;
}
}
对于那些想要入侵的人:
public static int GetNativeThreadId(Thread thread)
{
var f = typeof(Thread).GetField("DONT_USE_InternalThread",
BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
var pInternalThread = (IntPtr)f.GetValue(thread);
var nativeId = Marshal.ReadInt32(pInternalThread, (IntPtr.Size == 8) ? 548 : 348); // found by analyzing the memory
return nativeId;
}
根据MSDN:
一个操作系统ThreadId没有 与托管的固定关系 线程,因为非托管主机可以 控制之间的关系 托管和非托管线程。 具体来说,一个复杂的主机可以 使用CLR托管API来调度 许多托管线程针对同一个线程 操作系统线程,或移动一个 不同线程之间的托管线程 操作系统线程。
所以基本上,Thread对象并不一定对应于OS线程——这就是为什么它没有暴露本机ID的原因。
System.Threading.Thread.CurrentThread.Name
System.Threading.Thread.CurrentThread.ManagedThreadId
例如,在c#中调试线程时,你可以看到每个线程的ID。
这将是托管线程的id。ManagedThreadId是Thread的成员,所以你可以从任何Thread对象中获得Id。这将得到你当前的ManagedThreadID:
Thread.CurrentThread.ManagedThreadId
要通过OS线程ID(而不是ManagedThreadID)获取一个OS线程,您可以尝试linq。
int unmanagedId = 2345;
ProcessThread myThread = (from ProcessThread entry in Process.GetCurrentProcess().Threads
where entry.Id == unmanagedId
select entry).First();
似乎没有办法枚举托管线程,ProcessThread和Thread之间也没有关系,因此通过其Id获取托管线程非常困难。
有关托管线程与非托管线程的更多详细信息,请参阅这篇MSDN文章。