Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

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.

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?

ie.

Thread[] activeThreads = ?? 

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.)

like image 824
Lasse V. Karlsen Avatar asked Dec 01 '09 12:12

Lasse V. Karlsen


People also ask

How do I find the number of active threads?

activeCount() method returns the number of active threads in the current thread's thread group.

Which method returns the thread objects of all active threads?

The activeCount() method of thread class is used to return the number of active threads in the current thread's thread group.

How do I see active threads in python?

We can discover the number of active threads in a Python process. This can be achieved via the threading. active_count() function that returns an integer that indicates the number threads that are “alive“.


2 Answers

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.

like image 38
Winston Smith Avatar answered Oct 13 '22 21:10

Winston Smith


If you're willing to replace your application's Thread creations 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:

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.

like image 111
Jesse C. Slicer Avatar answered Oct 13 '22 22:10

Jesse C. Slicer