获取.NET中当前活动的托管线程列表?

对于“支持日志信息”类型的函数,我想枚举并转储活动的线程信息。

我很清楚竞争条件可能会使这些信息半不准确,但我想尝试获得最佳结果,即使它不是100%准确。

我查看了Process.Threads,但是它返回了ProcessThread对象,我想要一个Thread对象的集合,这样我就可以记录它们的名字,以及它们是否是后台线程。

是否有这样的集合可用,即使它只是我调用它时活动线程的快照?

即。

Thread[] activeThreads = ?? 

注意,要说清楚,我不是在询问Process.Threads,这个集合给了我很多,但并不是我想要的全部。 我想知道我们的应用程序当前正在使用多少时间特定的命名线程(这意味着我将不得不考虑稍后连接两种类型的对象,但名称比开始时的CPU时间更重要。)

如果您愿意用另一个包装类替换应用程序的Thread创建,则表示包装类可以为您跟踪活动和非活动的Thread 。 这是一个这样的包装器的最小可行shell:

 namespace ThreadTracker { using System.Collections.Generic; using System.Collections.ObjectModel; using System.Threading; public class TrackedThread { private static readonly IList threadList = new List(); private readonly Thread thread; private readonly ParameterizedThreadStart start1; private readonly ThreadStart start2; public TrackedThread(ParameterizedThreadStart start) { this.start1 = start; this.thread = new Thread(this.StartThreadParameterized); lock (threadList) { threadList.Add(this.thread); } } public TrackedThread(ThreadStart start) { this.start2 = start; this.thread = new Thread(this.StartThread); lock (threadList) { threadList.Add(this.thread); } } public TrackedThread(ParameterizedThreadStart start, int maxStackSize) { this.start1 = start; this.thread = new Thread(this.StartThreadParameterized, maxStackSize); lock (threadList) { threadList.Add(this.thread); } } public TrackedThread(ThreadStart start, int maxStackSize) { this.start2 = start; this.thread = new Thread(this.StartThread, maxStackSize); lock (threadList) { threadList.Add(this.thread); } } public static int Count { get { lock (threadList) { return threadList.Count; } } } public static IEnumerable ThreadList { get { lock (threadList) { return new ReadOnlyCollection(threadList); } } } // either: (a) expose the thread object itself via a property or, // (b) expose the other Thread public methods you need to replicate. // This example uses (a). public Thread Thread { get { return this.thread; } } private void StartThreadParameterized(object obj) { try { this.start1(obj); } finally { lock (threadList) { threadList.Remove(this.thread); } } } private void StartThread() { try { this.start2(); } finally { lock (threadList) { threadList.Remove(this.thread); } } } } } 

和它的快速测试驱动程序(注意我不迭代线程列表,只是获取列表中的计数):

 namespace ThreadTracker { using System; using System.Threading; internal static class Program { private static void Main() { var thread1 = new TrackedThread(DoNothingForFiveSeconds); var thread2 = new TrackedThread(DoNothingForTenSeconds); var thread3 = new TrackedThread(DoNothingForSomeTime); thread1.Thread.Start(); thread2.Thread.Start(); thread3.Thread.Start(15); while (TrackedThread.Count > 0) { Console.WriteLine(TrackedThread.Count); } Console.ReadLine(); } private static void DoNothingForFiveSeconds() { Thread.Sleep(5000); } private static void DoNothingForTenSeconds() { Thread.Sleep(10000); } private static void DoNothingForSomeTime(object seconds) { Thread.Sleep(1000 * (int)seconds); } } } 

不确定你是否可以采用这样的方法,但如果你能够在开发的早期阶段进行整合,它将实现目标。

在应用程序中创建每个线程时,是否可以在查找中存储线程信息?

每个线程启动时,您可以使用AppDomain.GetCurrentThreadId()获取其ID。 稍后,您可以使用它来与Process.Threads返回的数据进行交叉引用。