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

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

Getting list of currently active managed threads in .NET?

c#.netmultithreadingcollections

提问by Lasse V. Karlsen

For a "log information for support" type of function I'd like to enumerate and dump active thread information.

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

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.

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

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.

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

Is there such a collection available, even if it is just a snapshot of the active threads when I call it?

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

ie.

IE。

Thread[] activeThreads = ??

Note, to be clear, I am notasking 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.)

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

采纳答案by Jesse C. Slicer

If you're willing to replace your application's Threadcreations with another wrapper class, said wrapper class can track the active and inactive Threads for you. Here's a minimal workable shell of such a wrapper:

如果您愿意Thread用另一个包装类替换您的应用程序的创建,所述包装类可以Thread为您跟踪 active 和 inactive s。这是这种包装器的最小可行外壳:

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.

不确定您是否可以走这样的路线,但如果您能够在开发的早期阶段进行合并,它将实现目标。

回答by Winston Smith

Is it feasible for you to store thread information in a lookup as you create each thread in your application?

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

As each thread starts, you can get its ID using AppDomain.GetCurrentThreadId(). Later, you can use this to cross reference with the data returned from Process.Threads.

当每个线程启动时,您可以使用AppDomain.GetCurrentThreadId(). 稍后,您可以使用它与从Process.Threads.