C# 获取线程列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10315862/
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-09 13:19:21  来源:igfitidea点击:

Get list of threads

c#multithreadinglist

提问by sanchop22

I want to list all running threads but not by using the List<>class. I want to dynamically observe running threads. How can I do that?

我想列出所有正在运行的线程,但不使用List<>该类。我想动态观察正在运行的线程。我怎样才能做到这一点?

采纳答案by Xaqron

using System.Diagnostics;

ProcessThreadCollection currentThreads = Process.GetCurrentProcess().Threads;

foreach (ProcessThread thread in currentThreads)    
{
   // Do whatever you need
}

回答by Contango

Method 1: Get OS Threads

方法一:获取操作系统线程

This gets the list of OS threads:

这将获取操作系统线程列表:

ProcessThreadCollection currentThreads = Process.GetCurrentProcess().Threads;

foreach (ProcessThread thread in currentThreads)
{
}

Method 2: Get Managed Threads

方法 2:获取托管线程

Managed threads sit on top of OS threads. The IDs are different, and in theory, more than one Managed Thread may sit on top of a single OS thread (although I havn't actually observed this).

托管线程位于操作系统线程之上。这些 ID 是不同的,理论上,一个操作系统线程之上可能有多个托管线程(尽管我实际上没有观察到这一点)。

It turns out that getting managed threads is trickier than it really should be.

事实证明,获取托管线程比实际情况更棘手。

Method 2.1: Simplest code to get Managed Threads

方法 2.1:获取托管线程的最简单代码

  1. Check out Microsoft.Diagnostics.Runtime on GitHub.
  2. Install NuGet package CLR Memory Diagnostics (ClrMD).
  1. 在 GitHub 上查看Microsoft.Diagnostics.Runtime
  2. 安装 NuGet 包CLR 内存诊断 (ClrMD)

You can then use said NuGet package to attach to your own process, and read the managed threads out:

然后,您可以使用上述 NuGet 包附加到您自己的进程,并读取托管线程:

using Microsoft.Diagnostics.Runtime;

using (DataTarget target = DataTarget.AttachToProcess(
    Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive))
{
    ClrRuntime runtime = target.ClrVersions.First().CreateRuntime();
    foreach (ClrThread thread in runtime.Threads)
    {
    }
}

Method 2.2: Example of how to search through managed threads by stack trace

方法 2.2:如何通过堆栈跟踪搜索托管线程的示例

Unfortunately, I couldn't find any way to search through the list of threads by the thread name.

不幸的是,我找不到通过线程名称搜索线程列表的任何方法。

However, all is not lost: here is an example of how to create a managed thread, then find it by searching through the stack frames for a match on the namespace, then print out its properties:

然而,一切都没有丢失:这是一个如何创建托管线程的示例,然后通过在堆栈帧中搜索名称空间上的匹配项来找到它,然后打印出其属性:

namespace MyTest
{
    int managedThreadId = 0;
    var task = Task.Run(
        () =>
        {
            // Unfortunately, cant see "Testing" anywhere in result returned
            // from NuGet package ClrMD ...
            Thread.CurrentThread.Name = "Testing";
            Thread.Sleep(TimeSpan.FromDays(1));
        });


    // ... so we look for our thread by the first word in this namespace.
    string startOfThisNamespace = this.GetType().Namespace.ToString().Split('.')[0]; // Is "MyTest".
    using (DataTarget target = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive))
    {
        ClrRuntime runtime = target.ClrVersions.First().CreateRuntime();

        foreach (ClrThread thread in runtime.Threads)
        {
            IList<ClrStackFrame> stackFrames = thread.StackTrace;

            List<ClrStackFrame> stackframesRelatedToUs = stackFrames
                .Where(o => o.Method != null && o.Method.ToString().StartsWith(startOfThisNamespace)).ToList();

            if (stackframesRelatedToUs.Count > 0)
            {
                Console.Write("ManagedThreadId: {0}, OSThreadId: {1}, Thread: IsAlive: {2}, IsBackground: {3}:\n", thread.ManagedThreadId, thread.OSThreadId, thread.IsAlive, thread.IsBackground);
                Console.Write("- Stack frames related namespace '{0}':\n", startOfThisNamespace);
                foreach (var s in stackframesRelatedToUs)
                {
                    Console.Write("  - StackFrame: {0}\n", s.Method.ToString());
                }
            }
        }
    }
}

You can also find the correct match by saving ManagedThreadIdwithin the thread that you create, then looking for this same ID in runtime.Threads.

您还可以通过保存ManagedThreadId在您创建的线程中来找到正确的匹配项,然后在runtime.Threads.

Testing

测试

Tested with all combinations of:

使用以下所有组合进行测试:

  • Visual Studio 2015 SP1
  • .NET 4.5
  • .NET 4.6.0
  • .NET 4.6.1
  • C# 5.0
  • C# 6.0
  • 视觉工作室 2015 SP1
  • .NET 4.5
  • .NET 4.6.0
  • .NET 4.6.1
  • C# 5.0
  • C# 6.0

References

参考

See ClrMd throws exception when creating runtime.

请参阅ClrMd 在创建运行时抛出异常