web-dev-qa-db-ja.com

スレッドからスレッドIDを取得する

たとえばC#では、スレッドのデバッグ時に、各スレッドのIDを確認できます。

私はプログラム的に同じスレッドを取得する方法を見つけることができませんでした。現在のスレッドのIDを取得することさえできませんでした(Thread.currentThreadのプロパティ内)。

それで、Visual StudioはどのようにスレッドのIDを取得するのでしょうか。たとえば、id 2345のスレッドのハンドルを取得する方法はありますか。

293
LolaRun

GetThreadId は、指定されたネイティブスレッドのIDを返します。マネージスレッドで動作させる方法はいくつかあります。スレッドハンドルだけを見つけてそれをその関数に渡すことだけが必要です。

GetCurrentThreadId は現在のスレッドのIDを返します。

GetCurrentThreadIdは.NET 2.0以降では推奨されていません。推奨される方法は Thread.CurrentThread.ManagedThreadId プロパティです。

411
Blindy

たとえばC#では、スレッドのデバッグ時に、各スレッドのIDを確認できます。

これが管理対象スレッドのIDになります。 ManagedThreadIdThreadのメンバーなので、任意の Thread objectからIDを取得できます。これにより、現在の ManagedThreadID になります。

Thread.CurrentThread.ManagedThreadId

OSスレッドID(ManagedThreadIDではなく)でOSスレッドを取得するには、少しlinqを試してください。

int unmanagedId = 2345;
ProcessThread myThread = (from ProcessThread entry in Process.GetCurrentProcess().Threads
   where entry.Id == unmanagedId 
   select entry).First();

マネージスレッドを列挙する方法はなく、ProcessThreadとThreadの間の関係もないため、Idでマネージスレッドを取得するのは困難です。

管理スレッドと非管理スレッドの詳細については、 このMSDNの記事 を参照してください。

70
badbod99

現在実行中のスレッドのIDを取得するには、廃止予定の AppDomain.GetCurrentThreadId を使用できます。このメソッドは、Win32 APIメソッドGetCurrentThreadIDに対してPInvokeを使用し、WindowsのスレッドIDを返します。

.NET Threadオブジェクトは単一のWindowsスレッドに対応していないため、このメソッドは非推奨とマークされています。したがって、特定の.NETスレッドに対してWindowsから返される可能性のある安定したIDはありません。

これが事実であるより多くの理由のためにコンフィギュレータの答えを見てください。

41
Paul Turner

OS IDを取得するには

AppDomain.GetCurrentThreadId()
29
Mark Byers

MSDN によると、

非管理対象ホストが管理対象スレッドと非管理対象スレッド間の関係を制御できるため、オペレーティングシステムのThreadIdは管理対象スレッドと固定の関係にありません。特に、洗練されたホストはCLRホスティングAPIを使用して、同じオペレーティングシステムスレッドに対して多数の管理スレッドをスケジュールしたり、異なるオペレーティングシステムスレッド間で管理スレッドを移動したりできます。

そのため、基本的に、Threadオブジェクトは必ずしもOSスレッドに対応するわけではありません - ネイティブIDが公開されていないのはこのためです。

21
configurator

ハックしようとしている人のために:

    public static int GetNativeThreadId(Thread thread)
    {
        var f = typeof(Thread).GetField("DONT_USE_InternalThread",
            BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);

        var pInternalThread = (IntPtr)f.GetValue(thread);
        var nativeId = Marshal.ReadInt32(pInternalThread, (IntPtr.Size == 8) ? 548 : 348); // found by analyzing the memory
        return nativeId;
    }
13
ezolotko

現在のスレッドIDを見つけるには - Thread.CurrentThread.ManagedThreadIdを使います。しかしこの場合、現在のwin32スレッドIDが必要になるかもしれません - この関数でそれを取得するにはpInvokeを使用してください。

[DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
public static extern Int32 GetCurrentWin32ThreadId();

まず管理スレッドIDとwin32スレッドIDの接続を保存する必要があります - win32 IDを管理スレッドにマッピングする辞書を使用します。

次に、そのIDでスレッドを見つけるために、Process.GetCurrentProcess()。Threadsを使ってプロセスのスレッドを反復処理し、そのIDを持つスレッドを見つけます。

foreach (ProcessThread thread in Process.GetCurrentProcess().Threads)
{
     var managedThread = win32ToManagedThread[thread.id];
     if((managedThread.ManagedThreadId == threadId)
     {
         return managedThread;
     }
}
10
Dror Helper

Windows 10でのオフセットは0x022C(x 64ビットアプリケーション)と0x0160(x 32ビットアプリケーション)です。

public static int GetNativeThreadId(Thread thread)
{
    var f = typeof(Thread).GetField("DONT_USE_InternalThread",
        BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);

    var pInternalThread = (IntPtr)f.GetValue(thread);
    var nativeId = Marshal.ReadInt32(pInternalThread, (IntPtr.Size == 8) ? 0x022C : 0x0160); // found by analyzing the memory
    return nativeId;
}
7

マネージコードから、各マネージスレッドのThread型のインスタンスにアクセスできます。 ThreadはOSスレッドの概念をカプセル化したものであり、現在のCLRの時点ではマネージスレッドとOSスレッドは1対1で対応しています。ただし、これは実装の詳細であり、将来変更される可能性があります。

Visual Studioによって表示されるIDは、実際にはOSのスレッドIDです。これはではないいくつかの回答で示唆されているマネージスレッドIDと同じではありません。

Thread型には、基礎となるOS構造を指すDONT_USE_InternalThreadというプライベートIntPtrメンバフィールドが含まれています。ただし、これは実際には実装の詳細なので、このIMOを実行することはお勧めできません。そして名前の種類はあなたがこれに頼るべきでないことを示します。

5
Brian Rasmussen

System.Threading.Thread.CurrentThread.Name

System.Threading.Thread.CurrentThread.ManagedThreadId
4
Manu

マネージスレッドIDを返すThread.GetHashCodeを使用できます。もしあなたがGetHashCodeの目的を考えているなら、これは理にかなっています - それはオブジェクト(スレッド)のためのユニークな識別子(例えば辞書のキー)である必要があります。

Threadクラスの 参照ソース はここでは有益です。 (確かに、特定の.NET実装はこのソースコードに基づかないかもしれませんが、デバッグの目的で私は私のチャンスをつかむでしょう。)

GetHashCode は、「オブジェクトの等価性をすばやくチェックする必要があるアルゴリズムにこのハッシュコードを提供します」ので、スレッドの等価性をチェックするのに最適です。特定のメソッドが呼び出し元のスレッドで実行されていることを表明する。

3
yoyo