2011-04-11 36 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