Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you're willing to replace your application's <code>Thread</code> creations with another wrapper class, said wrapper class can track the active and inactive <code>Thread</code>s for you. Here's a minimal workable shell of such a wrapper:</p> <pre><code>namespace ThreadTracker { using System.Collections.Generic; using System.Collections.ObjectModel; using System.Threading; public class TrackedThread { private static readonly IList&lt;Thread&gt; threadList = new List&lt;Thread&gt;(); 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&lt;Thread&gt; ThreadList { get { lock (threadList) { return new ReadOnlyCollection&lt;Thread&gt;(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); } } } } } </code></pre> <p>and a quick test driver of it (note I do not iterate over the list of threads, merely get the count in the list):</p> <pre><code>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 &gt; 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); } } } </code></pre> <p>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.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload