2011-04-11 14 views
7

Bir işlem olarak, bir süreç içindeki O/S süreçlerini ve O/S iş parçacıklarını görüntülemek için bir kod yazıyordum (Sysinternals process explorer gibi). _real_ thread kimliğini CLR "arkadaşça" şekilde nasıl edinebilirim?

O .NET'in ManagedThreadId (ler) O/S iplik kimlikleri değildir bulundu. Biraz okumadan sonra AppDomain.GetCurrentThreadId() ile karşılaştım. Ne yazık ki, bu işlev "eskimiş" olarak işaretlenmiştir (bu, gelecekte "mevcut değil" anlamına gelebilir). Bulduğum bir çözüm, doğrudan Win32 GetCurrentThreadId çağırmak için InteropServices kullanmaktır. Bununla iyiyim, ama .net felsefesine karşı geliyor.

Sorum şu: Bir CLR akım dişin gerçek kimliği elde etme "dost" yolu var mı? Başvuru için

, burada şimdiye kadar ne denedim gösteren kod snippet'idir. // 1 ve // ​​2 ekran doğru diş kimliği // 3 ve // ​​4 bir CLR dostu bir şekilde aynı bilgi edinme girişimleri vardı (ama çalışmıyor.)

Yardımlarınız için teşekkür ederim

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

Neden CLR istemek sadece CLR "düşmanca" işlemlerini yürütmek hangi üzerinde "düşmanca" verileri CLR bir parça almak için "Dost" yolu olur? – Polity

+0

@Polity: Sistem yardımcı programlarını yazıyorum ve çoğunun .net ile hiçbir ilgisi yok. Eğer .net programladığımda, ilgilendiğim bilgiler .net ortamıyla ilgili olmasa bile .net için "dost" olmak isterim. – Hex440bx

+0

Eh, benim durumum geçerli kalıyor :) Bir arabanın bir parçasını çelikten, diğerini tahtadan inşa etmek için bir sebep yok. Sadece yerel sistem API'leri ile kullanmak için yerel bir threadID i .NET dostu bir yol elde etmek için bir neden yoktur gibi. Bu durumda win32'nin GetCurrentThreadId kullanımı mükemmel bir şekilde geçerlidir! – Polity

cevap

9

GetCurrentThreadId içine PInvoking en iyi bahis ve size doğru bilgi verecektir. Sizi uyarmalıyım Ancak

, CLR bu bilgi sağlamaz neden çok iyi nedenler vardır: neredeyse yönetilen kod için tamamen yararsız bir değerdir. Bu, ömrü boyunca birkaç farklı yerel iş parçacığı tarafından desteklenen tek bir yönetilen iş parçacığı için bir CLR perspektifinden tamamen yasaldır. Bu, GetCurrentThreadId sonucunun, bir iş parçacığının kullanım ömrü boyunca değiştirilebileceği anlamına gelir. Birçok uygulamada bu gözlemlenebilir bir olgu değildir. Bir UI uygulamasında bu aslında gerçekleşmeyecektir çünkü genellikle COM birlikte çalışma sorunları nedeniyle takas etmek için daha zor (genellikle hatta yasadışı) bir STA iş parçacığı tarafından desteklenmektedir. Pek çok geliştirici bundan kesinlikle habersiz. Ancak, tipik olarak arka plan iş parçasının yürütme bağlamı olan başlık altındaki MTA iş parçacığının takas edilmesi çok kolaydır.

+0

Teşekkürler. .net konuları ile O/S konuları arasındaki farkın farkındayım (bu yüzden Sysinternals'ın Process Explorer'ından bahsetmiştim). Cevabınızdan, O/S 'nin PInvoking dışındaki mevcut parçasını almanın CLR yolu olmadığını anlıyorum. Bir cevap seçmeden önce diğer önerileri bekleyeceğim. – Hex440bx

+0

@ Hex440bx Yerel kimliğin yönetilen koddan elde edilmesinin her yolunun 2.0'da kullanımdan kaldırılmasının kesin olarak eminim. – JaredPar

-1

Bu bir nedenden dolayı eskiden; Gelecekte olan 'gerçek' iş parçacığı kimliğinin sabit olmaması veya .NET iş parçacıkları arasında paylaşılabileceği fikri.

+0

@Kieren: .net'te bir şeyi "manipüle etmek" bilgisine gitmiyorum, sadece O/S düzeyinde kullanacağım (örneğin Process Explorer gibi).) – Hex440bx

+0

Bu çelişki, yukarıda bahsettiğim problemleri içeren mevcut thread ID'yi arıyor gibi görünüyor; point bir .NET iş parçacığının mutlaka bir O/S iş parçacığına eşit olması gerekmez. –

+0

@Kieren:. Net ve O/S iş parçacıkları hakkındaki noktanızı anlıyorum. Demek istediğim, eğer C# (ve .net açık olarak) kullanarak Process Explorer gibi bir yardımcı program yazmak istediysem, O/S seviyesinde doğru olan bilgiyi sağlarken .net felsefesine sadık kalarak yapılabilirdi. – Hex440bx

İlgili konular