作为练习,我正在编写一些代码来显示进程中的 O/S 进程和 O/S 线程(就像 Sysinternals 进程浏览器所做的那样)。
我发现 .net 的 ManagedThreadId(s) 不是 O/S 线程 ID。经过一番阅读后,我发现了 AppDomain.GetCurrentThreadId()。不幸的是,该功能被标记为“过时”(这可能意味着将来“不可用”)。我找到的一种解决方案是使用 InteropServices 直接调用 Win32 GetCurrentThreadId。我对此没有意见,但感觉与 .net 理念背道而驰。
我的问题是:是否有一种 CLR“友好”的方式来获取当前线程的真实 ID?
作为引用,这里有一段代码显示了我到目前为止所尝试的内容。//1 和//2 显示正确的线程 ID,//3 和//4 试图以 CLR 友好的方式获取相同的信息(但它们不起作用。)
谢谢你的帮助,
约翰。
[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId();
static void Main(string[] args)
{
// AppDomain.GetCurrentThreadId() is "obsolete"
int ThreadId1 = AppDomain.GetCurrentThreadId(); // 1
// not the ".net" way of doing things
int ThreadId2 = GetCurrentThreadId(); // 2
// "no joy" attempts to get the same results I got above
int ThreadId3 = Process.GetCurrentProcess().Threads[0].Id; // 3
int ThreadId4 = Thread.CurrentThread.ManagedThreadId; // 4
Console.WriteLine("ThreadId1: {0}, ThreadId2: {1}, ThreadId3: {2}, " +
"ThreadId4: {3}",
ThreadId1, ThreadId2, ThreadId3, ThreadId4);
}
最佳答案
PInvoking into the GetCurrentThreadId
是你最好的选择,它会给你正确的信息。
但是我必须警告您,CLR 不提供此信息的原因非常充分:对于托管代码而言,它几乎是一个完全无用的值。从 CLR 的角度来看,单个托管线程在其生命周期内由多个不同的 native 线程支持是完全合法的。这意味着 GetCurrentThreadId
的结果可以(并且将会)在线程的整个生命周期中发生变化。
在许多应用程序中,这不是可观察到的现象。在 UI 应用程序中,这实际上不会发生,因为它通常由 STA 线程支持,由于 COM 互操作问题,该线程更难(通常甚至是非法的)换出。如此多的开发人员对此一无所知。然而,在幕后更换 MTA 线程非常容易,这通常是后台线程的执行上下文。
关于c# - 如何以 CLR "friendly"方式获取_real_ 线程 ID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5624128/