c# - 如何以 CLR "friendly"方式获取_real_ 线程 ID?

标签 c# winapi

作为练习,我正在编写一些代码来显示进程中的 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/

相关文章:

c# - 在云应用程序中使用 session 是否安全

windows - 如何从管理进程以当前用户权限运行进程

c# - 特殊(或外国)字符

c# - SaveFileDialog 阻止可移动驱动器

c++ - 当我想发送 "num8"时,SendInput 发送 "vk_up"?怎么会?

c++ - 每个Windows服务都会调用其可执行的main函数吗?

unicode - Win32 API 函数需要什么编码?

c - 我如何在 XP 中使用 c 程序访问磁盘的原始扇区?

c# - 将重复的目录移回根目录

c# - 根据时间通过 LINQ to Entities (EF) 连接同一个表