[C#] 스레드에서 스레드 ID 얻기

예를 들어 C #에서 스레드를 디버깅 할 때 각 스레드의 ID를 볼 수 있습니다.

프로그래밍 방식으로 동일한 스레드를 얻는 방법을 찾을 수 없습니다. 현재 스레드의 ID를 (의 속성에서 Thread.currentThread) 가져올 수 없었습니다 .

따라서 Visual Studio에서 스레드의 ID를 얻는 방법이 궁금합니다. 2345예를 들어 id를 사용하여 스레드의 핸들을 얻는 방법이 있습니까?



답변

GetThreadId주어진 네이티브 스레드의 ID를 반환합니다. 관리되는 스레드와 작동하게하는 방법이 있습니다. 스레드 핸들 만 찾아 해당 기능에 전달해야합니다.

GetCurrentThreadId 현재 스레드의 ID를 반환합니다.

GetCurrentThreadId.NET 2.0에서 더 이상 사용되지 않습니다. 권장되는 방법은 Thread.CurrentThread.ManagedThreadId속성입니다.


답변

예를 들어 C #에서 스레드를 디버깅 할 때 각 스레드의 ID를 볼 수 있습니다.

관리되는 스레드의 ID가됩니다. ManagedThreadId의 멤버 Thread이므로 모든 Thread 객체 에서 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와 스레드 사이의 관계가없는 것 같으므로 ID로 관리되는 스레드를 얻는 것은 어려운 일입니다.

관리 및 비 관리 스레딩에 대한 자세한 내용은 이 MSDN arcticle을 참조하십시오 .


답변

더 이상 사용되지 않는 AppDomain.GetCurrentThreadId것을 사용하여 현재 실행중인 스레드의 ID를 얻을 수 있습니다 . 이 메소드는 PInvoke를 Win32 API 메소드 GetCurrentThreadID로 사용하고 Windows 스레드 ID를 리턴합니다.

이 메서드는 .NET Thread 개체가 단일 Windows 스레드에 해당하지 않으므로 Windows에서 지정된 .NET 스레드에 대해 반환 할 수있는 안정적인 ID가 없기 때문에 더 이상 사용되지 않는 것으로 표시됩니다.

이것이 더 많은 이유에 대해서는 구성 자의 답변을 참조하십시오.


답변

OS ID를 얻으려면 다음을 사용하십시오.

AppDomain.GetCurrentThreadId()


답변

MSDN 에 따르면 :

관리되지 않는 호스트는 관리되는 스레드와 관리되지 않는 스레드 간의 관계를 제어 할 수 있으므로 운영 체제 ThreadId는 관리되는 스레드와 고정 된 관계가 없습니다. 특히, 정교한 호스트는 CLR 호스팅 API를 사용하여 동일한 운영 체제 스레드에 대해 많은 관리되는 스레드를 예약하거나 다른 운영 체제 스레드간에 관리되는 스레드를 이동할 수 있습니다.

따라서 기본적으로 Thread객체는 반드시 OS 스레드와 일치하지 않아도되므로 기본 ID가 노출되지 않습니다.


답변

해킹하려는 사람들을 위해 :

    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;
    }


답변

현재 쓰레드 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;
     }
}