2011-04-11 98 views
7

作为一个练习,我正在编写一些代码来显示进程内的O/S进程和O/S线程(如Sysinternals进程管理器)。如何以CLR“友好”方式获得_real_线程ID?

我发现.net的ManagedThreadId(s)不是O/S线程标识符。读了一下之后,我发现AppDomain.GetCurrentThreadId()。不幸的是,该功能被标记为“过时”(这可能意味着未来“不可用”)。我找到的一个解决方案是使用InteropServices直接调用Win32 GetCurrentThreadId。我对此感觉很好,但它与.net哲学相反。

我的问题是:是否有CLR“友好”的方式获得当前线程的真实ID?

仅供参考,以下是代码片段,展示了迄今为止我所尝试的内容。 // 1和// 2显示正确的线程ID,// 3和// 4尝试以CLR友好的方式获取相同的信息(但它们不起作用)。

谢谢你的帮助,

John。

[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); 
} 
+2

为什么要CLR“友好”的方式来获得一段CLR“不友好”的数据,在这个数据上只能执行CLR的“不友好”操作? – Polity 2011-04-11 16:07:34

+0

@Polity:我编写的系统实用程序,其中大部分与.net无关。如果我用.net编程,即使我感兴趣的信息与.net环境无关,我也希望对.net“友好”。 – Hex440bx 2011-04-11 16:14:19

+0

那么,我的观点仍然有效:)没有理由用钢制造汽车的一部分,而用木头制造另一部分汽车。就像没有理由得到一个本地的threadID我只是一个.NET友好的方式,只用它与本地系统API的。在这种情况下使用win32的GetCurrentThreadId是完全有效的! – Polity 2011-04-11 16:29:48

回答

9

PInvoking到GetCurrentThreadId是你最好的选择,并会给你正确的信息。

但是我必须警告你,为什么CLR不提供这些信息有很好的理由:对于托管代码来说,这几乎是一个完全无用的值。从CLR的角度来看,单个托管线程在其生命周期中由多个不同的本地线程支持是完全合法的。这意味着GetCurrentThreadId的结果可以(且将会)在线程的整个生命周期中发生变化。

在许多应用中,这不是一个可观察的现象。在一个UI应用程序中,这不会实际发生,因为它通常由一个STA线程支持,由于COM互操作问题,它更难以更换(通常甚至是非法的)。许多开发人员都对此非常无知。然而,在通常是后台线程的执行上下文的情况下,很容易换掉MTA线程。

+0

谢谢。我知道.net线程和O/S线程之间的区别(这就是为什么我提到了Sysinternals的Process Explorer)。从你的回复中我可以得出,除了PInvoking之外,没有CLR获得O/S当前线程的方式。在选择答案之前,我会等待其他建议。 – Hex440bx 2011-04-11 16:09:00

+0

@ Hex440bx我相当肯定,从托管代码获取本机ID的每种方式都在2.0中被弃用。 – JaredPar 2011-04-11 16:12:00

-1

这是过时的原因;这个想法在未来“实际”的线程ID可能不是恒定的,或者可能在.NET线程之间共享。

+0

@Kieren:我不会去“操纵”.net中的某些东西,我只会在O/S级别上使用它(例如,像Process Explorer那样。) – Hex440bx 2011-04-11 16:17:27

+0

矛盾似乎是你正在寻找当前的线程ID,它有我在上面提到的问题;关键是一个.NET线程不一定等于一个O/S线程 – 2011-04-11 16:20:04

+0

@Kieren:我理解你对.net和O/S线程的观点。我说的是,如果我想用C#(和.net)编写一个实用程序(如Process Explorer),是否可以坚持.net理念,同时提供在O/S级别准确的信息。 – Hex440bx 2011-04-11 16:24:01

相关问题