C# 从线程中获取线程 ID

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1679243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 19:56:59  来源:igfitidea点击:

Getting the thread ID from a thread

c#.netmultithreading

提问by LolaRun

In C# when debugging threads for example, you can see each thread's ID.

例如在 C# 中调试线程时,您可以看到每个线程的 ID。

I couldn't find a way to get that same thread, programmatically. I could not even get the ID of the current thread (in the properties of the Thread.currentThread).

我找不到以编程方式获得相同线程的方法。我什至无法获得当前线程的 ID(在 的属性中Thread.currentThread)。

So, I wonder how does Visual Studio get the IDs of the threads, and is there a way to get the handle of the thread with id 2345, for example?

所以,我想知道 Visual Studio 如何获取线程的 ID,例如,有没有办法使用 id 获取线程的句柄2345

采纳答案by Blindy

GetThreadIdreturns the ID of a given native thread. There are ways to make it work with managed threads, I'm sure, all you need to find is the thread handle and pass it to that function.

GetThreadId返回给定本机线程的 ID。有很多方法可以使它与托管线程一起工作,我敢肯定,您只需要找到线程句柄并将其传递给该函数即可。

GetCurrentThreadIdreturns the ID of the current thread.

GetCurrentThreadId返回当前线程的 ID。

GetCurrentThreadIdhas been deprecated as of .NET 2.0: the recommended way is the Thread.CurrentThread.ManagedThreadIdproperty.

GetCurrentThreadId自 .NET 2.0 起已弃用:推荐的方式是Thread.CurrentThread.ManagedThreadId属性。

回答by Mark Byers

To get the OS ID use:

要获取操作系统 ID,请使用:

AppDomain.GetCurrentThreadId()

回答by Manu

System.Threading.Thread.CurrentThread.Name

System.Threading.Thread.CurrentThread.Name

System.Threading.Thread.CurrentThread.ManagedThreadId

回答by Dror Helper

To find the current thread Id use - `Thread.CurrentThread.ManagedThreadId'. But in this case you might need the current win32 thread id - use pInvoke to get it with this function:

要查找当前线程 ID,请使用 - `Thread.CurrentThread.ManagedThreadId'。但在这种情况下,您可能需要当前的 win32 线程 id - 使用 pInvoke 通过此函数获取它:

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

First you'll need to save the managed thread id and win32 thread id connection - use a dictionary that maps a win32 id to managed thread.

首先,您需要保存托管线程 id 和 win32 线程 id 连接 - 使用将 win32 id 映射到托管线程的字典。

Then to find a thread by it's id iterate over the process's thread using Process.GetCurrentProcess().Threads and find the thread with that id:

然后通过它的 id 找到一个线程,使用 Process.GetCurrentProcess().Threads 遍历进程的线程并找到具有该 id 的线程:

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

回答by Brian Rasmussen

From managed code you have access to instances of the Threadtype for each managed thread. Threadencapsulates the concept of an OS thread and as of the current CLR there's a one-to-one correspondance with managed threads and OS threads. However, this is an implementation detail, that may change in the future.

从托管代码中,您可以访问Thread每个托管线程的类型实例。Thread封装了 OS 线程的概念,从当前的 CLR 开始,托管线程和 OS 线程之间存在一对一的对应关系。但是,这是一个实现细节,将来可能会发生变化。

The ID displayed by Visual Studio is actually the OS thread ID. This is notthe same as the managed thread ID as suggested by several replies.

Visual Studio 显示的 ID 实际上是 OS 线程 ID。这是一样的托管线程ID几种答复的建议。

The Threadtype does include a private IntPtr member field called DONT_USE_InternalThread, which points to the underlying OS structure. However, as this is really an implementation detail it is not advisable to pursue this IMO. And the name sort of indicates that you shouldn't rely on this.

Thread类型确实包括一个名为 的私有 IntPtr 成员字段DONT_USE_InternalThread,它指向底层操作系统结构。但是,由于这确实是一个实施细节,因此不建议遵循此 IMO。这个名字有点表明你不应该依赖这个。

回答by configurator

According to MSDN:

根据MSDN

An operating-system ThreadId has no fixed relationship to a managed thread, because an unmanaged host can control the relationship between managed and unmanaged threads. Specifically, a sophisticated host can use the CLR Hosting API to schedule many managed threads against the same operating system thread, or to move a managed thread between different operating system threads.

操作系统 ThreadId 与托管线程没有固定的关系,因为非托管主机可以控制托管线程和非托管线程之间的关系。具体来说,复杂的主机可以使用 CLR 托管 API 来针对同一操作系统线程调度多个托管线程,或者在不同操作系统线程之间移动托管线程。

So basically, the Threadobject does not necessarily correspond to an OS thread - which is why it doesn't have the native ID exposed.

所以基本上,Thread对象不一定对应于操作系统线程 - 这就是它没有公开本机 ID 的原因。

回答by Paul Turner

You can use the deprecated AppDomain.GetCurrentThreadIdto get the ID of the currently running thread. This method uses a PInvoke to the Win32 API method GetCurrentThreadID, and will return the Windows thread ID.

您可以使用 deprecatedAppDomain.GetCurrentThreadId来获取当前正在运行的线程的 ID。此方法使用 PInvoke 到 Win32 API 方法GetCurrentThreadID,并将返回 Windows 线程 ID。

This method is marked as deprecated because the .NET Thread object does not correspond to a single Windows thread, and as such there is no stable ID which can be returned by Windows for a given .NET thread.

此方法被标记为已弃用,因为 .NET 线程对象不对应于单个 Windows 线程,因此对于给定的 .NET 线程,Windows 没有可以返回的稳定 ID。

See configurator's answer for more reasons why this is the case.

有关出现这种情况的更多原因,请参阅配置器的回答。

回答by badbod99

In C# when debugging threads for example, you can see each thread's ID.

例如在 C# 中调试线程时,您可以看到每个线程的 ID。

This will be the Ids of the managed threads. ManagedThreadIdis a member of Threadso you can get the Id from from any Threadobject. This will get you the current ManagedThreadID:

这将是托管线程的 ID。 ManagedThreadId是 的成员,Thread因此您可以从任何Thread对象获取 Id 。这将为您提供当前的ManagedThreadID

Thread.CurrentThread.ManagedThreadId

To get an OS thread by it's OS thread ID (not ManagedThreadID), you can try a bit of linq.

要通过操作系统线程 ID (不是 ManagedThreadID)获取操作系统线程,您可以尝试一些 linq。

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

It seems there is no way to enumerate the managed threads and no relation between ProcessThread and Thread, so getting a managed thread by it's Id is a tough one.

似乎没有办法枚举托管线程并且 ProcessThread 和 Thread 之间没有关系,因此通过它的 Id 获取托管线程是一个艰难的任务。

For more details on Managed vs Unmanaged threading see this MSDN arcticle.

有关托管与非托管线程的更多详细信息,请参阅此 MSDN 文章

回答by ezolotko

For those about to hack:

对于那些即将入侵的人:

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

回答by yoyo

You can use Thread.GetHashCode, which returns the managed thread ID. If you think about the purpose of GetHashCode, this makes good sense -- it needs to be a unique identifier (e.g. key in a dictionary) for the object (the thread).

您可以使用 Thread.GetHashCode,它返回托管线程 ID。如果您考虑 GetHashCode 的用途,这很有意义——它需要是对象(线程)的唯一标识符(例如字典中的键)。

The reference source for the Thread classis instructive here. (Granted, a particular .NET implementation maynot be based on this source code, but for debugging purposes I'll take my chances.)

Thread 类参考源在这里很有启发性。(当然,特定的 .NET 实现可能不是基于此源代码,但出于调试目的,我会抓住机会。)

GetHashCode"provides this hash code for algorithms that need quick checks of object equality," so it is well-suited for checking Thread equality -- for example to assert that a particular method is executing on the thread you wanted it called from.

GetHashCode“为需要快速检查对象相等性的算法提供此哈希码”,因此它非常适合检查线程相等性——例如,断言特定方法正在您希望调用它的线程上执行。