获取 .NET 中当前活动的托管线程的列表? [英] Getting list of currently active managed threads in .NET?
问题描述
对于支持日志信息"类型的函数,我想枚举和转储活动线程信息.
For a "log information for support" type of function I'd like to enumerate and dump active thread information.
我很清楚竞争条件可能会使此信息半不准确,但我想尝试获得最佳结果,即使它不是 100% 准确.
I'm well aware of the fact that race conditions can make this information semi-inaccurate, but I'd like to try to get the best possible result, even if it isn't 100% accurate.
我查看了 Process.Threads,但它返回 ProcessThread 对象,我想要一个 Thread 对象的集合,以便我可以记录它们的名称,以及它们是否是后台线程.
I looked at Process.Threads, but it returns ProcessThread objects, I'd like to have a collection of Thread objects, so that I can log their name, and whether they're background threads or not.
是否有这样的集合可用,即使它只是我调用时活动线程的快照?
Is there such a collection available, even if it is just a snapshot of the active threads when I call it?
即.
Thread[] activeThreads = ??
注意,要清楚,我不是询问 Process.Threads,这个集合给了我很多,但不是我想要的全部.我想知道我们的应用程序中特定命名线程当前使用了多少时间(这意味着我稍后将不得不查看连接这两种类型的对象,但名称比开始时的 CPU 时间更重要.)>
Note, to be clear, I am not asking about Process.Threads, this collection gives me a lot, but not all of what I want. I want to know how much time specific named threads in our application is currently using (which means I will have to look at connecting the two types of objects later, but the names is more important than the CPU time to begin with.)
推荐答案
如果您愿意将应用程序的 Thread
创建替换为另一个包装类,则该包装类可以跟踪活动和非活动 Thread
s 给你.这是这种包装器的最小可行外壳:
If you're willing to replace your application's Thread
creations with another wrapper class, said wrapper class can track the active and inactive Thread
s for you. Here's a minimal workable shell of such a wrapper:
namespace ThreadTracker
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
public class TrackedThread
{
private static readonly IList<Thread> threadList = new List<Thread>();
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<Thread> ThreadList
{
get
{
lock (threadList)
{
return new ReadOnlyCollection<Thread>(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);
}
}
}
}
}
以及它的快速测试驱动程序(注意我不会遍历线程列表,只是获取列表中的计数):
and a quick test driver of it (note I do not iterate over the list of threads, merely get the count in the list):
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);
}
}
}
不确定您是否可以走这样的路线,但如果您能够在开发的早期阶段进行合并,它将实现目标.
Not sure if you can go such a route, but it will accomplish the goal if you're able to incorporate at an early stage of development.
这篇关于获取 .NET 中当前活动的托管线程的列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!