static void Main(String[] args) { int minWorker, minIocp, maxWorker, maxIocp; MyOptions o = new MyOptions(); try { o.load(args); } catch (Exception) { o.usage(); Environment.Exit(1); } Console.WriteLine("Options:"); Console.WriteLine(o); if (o.blocking) { Console.WriteLine("\n-- Monitor .NET Thread Pool using a I/O-bound load\n"); } else { Console.WriteLine("\n-- Monitor .NET Thread Pool using a CPU-bound load\n"); } WorkerThreadReport.Verbose = true; ThreadPool.GetMinThreads(out minWorker, out minIocp); ThreadPool.GetMaxThreads(out maxWorker, out maxIocp); //ThreadPool.SetMinThreads(2 * Environment.ProcessorCount, minIocp); Console.WriteLine("-- processors: {0}; min/max workers: {1}/{2}; min/max iocps: {3}/{4}\n", Environment.ProcessorCount, minWorker, maxWorker, minIocp, maxIocp); Console.Write("--Hit <enter> to start, and then <enter> again to terminate..."); Console.ReadLine(); for (int i = 0; i < o.nactions; i++) { ThreadPool.QueueUserWorkItem((targ) => { WorkerThreadReport.RegisterWorker(); int tid = Thread.CurrentThread.ManagedThreadId; Console.WriteLine("-->Action({0}, #{1:00})", targ, tid); for (int n = 0; n < o.ntries; n++) { WorkerThreadReport.RegisterWorker(); if (!o.blocking) { Thread.SpinWait(o.execTime); // CPU-bound load } else { Thread.Sleep(o.blockTime); // I/O-bound load } } Console.WriteLine("<--Action({0}, #{1:00})", targ, tid); }, i); Thread.Sleep(o.injectionPeriod); } int delay = 50; do { int till = Environment.TickCount + delay; do { if (Console.KeyAvailable) { goto Exit; } Thread.Sleep(15); } while (Environment.TickCount < till); delay += 50; // // Comment the next statement to allow worker thread retirement! // /* * ThreadPool.QueueUserWorkItem(_ => { * WorkerThreadReport.RegisterWorker(); * Console.WriteLine("ExtraAction() --><-- on worker thread #{0}", Thread.CurrentThread.ManagedThreadId); * }); */ } while (true); Exit: Console.WriteLine("-- {0} worker threads were injected", WorkerThreadReport.CreatedThreads); WorkerThreadReport.ShowThreads(); WorkerThreadReport.ShutdownWorkerThreadReport(); }
static void Main(String[] args) { int minWorker, minIocp, maxWorker, maxIocp; if (args.Length != 1 || !(args[0].Equals("-cpu") || args[0].Equals("-io"))) { Console.WriteLine("usage: ThreadPoolMonitor [-cpu | -io]"); return; } bool cpuBoundWorkload = args[0].Equals("-cpu"); if (cpuBoundWorkload) { Console.WriteLine("--Monitor the .NET Framework's Thread Pool using a CPU-bound workload"); } else { Console.WriteLine("--Monitor the .NET Framework's Thread Pool using a I/O-bound workload"); } ThreadPool.GetMinThreads(out minWorker, out minIocp); ThreadPool.GetMaxThreads(out maxWorker, out maxIocp); //ThreadPool.SetMinThreads(2 * Environment.ProcessorCount, minIocp); Console.WriteLine("--processors: {0}; min/max workers: {1}/{2}; min/max iocps: {3}/{4}", Environment.ProcessorCount, minWorker, maxWorker, minIocp, maxIocp); Console.Write("--hit <enter> to start, and then <enter> again to terminate..."); Console.ReadLine(); for (int i = 0; i < ACTION_COUNT; i++) { ThreadPool.QueueUserWorkItem((targ) => { WorkerThreadReport.RegisterWorker(); int tid = Thread.CurrentThread.ManagedThreadId; Console.WriteLine($"-->Action({targ:D2}, #{tid:D2})"); for (int n = 0; n < REPEAT_FOR; n++) { WorkerThreadReport.RegisterWorker(); if (cpuBoundWorkload) { Thread.SpinWait(2500000); // CPU-bound workload } else { Thread.Sleep(50); // I/O-bound workload } } Console.WriteLine($"<--Action({targ:D2}, #{tid:00})"); }, i); } int delay = 50; do { int till = Environment.TickCount + delay; do { if (Console.KeyAvailable) { goto Exit; } Thread.Sleep(15); } while (Environment.TickCount < till); delay += 50; // // Comment the next statement to allow worker thread retirement! // /* * ThreadPool.QueueUserWorkItem(_ => { * WorkerThreadReport.RegisterWorker(); * Console.WriteLine("ExtraAction() --><-- on worker thread #{0}", Thread.CurrentThread.ManagedThreadId); * }); */ } while (true); Exit: Console.WriteLine($"-- {WorkerThreadReport.CreatedThreads} worker threads were injected"); WorkerThreadReport.ShowThreads(); WorkerThreadReport.ShutdownWorkerThreadReport(); }
static void Main() { int minWorker, minIocp, maxWorker, maxIocp; #if CPU_BOUND_LOAD Console.WriteLine("\n-- Monitor .NET Thread Pool using a CPU-bound load\n"); #else Console.WriteLine("\n-- Monitor .NET Thread Pool using a I/O-bound load\n"); #endif ThreadPool.GetMinThreads(out minWorker, out minIocp); ThreadPool.GetMaxThreads(out maxWorker, out maxIocp); //ThreadPool.SetMinThreads(2 * Environment.ProcessorCount, minIocp); Console.WriteLine("-- processors: {0}; min/max workers: {1}/{2}; min/max iocps: {3}/{4}\n", Environment.ProcessorCount, minWorker, maxWorker, minIocp, maxIocp); Console.Write("--Hit <enter> to start, and then <enter> again to terminate..."); Console.ReadLine(); for (int i = 0; i < ACTION_COUNT; i++) { ThreadPool.QueueUserWorkItem((targ) => { WorkerThreadReport.RegisterWorker(); int tid = Thread.CurrentThread.ManagedThreadId; Console.WriteLine("-->Action({0}, #{1:00})", targ, tid); for (int n = 0; n < REPEAT_FOR; n++) { WorkerThreadReport.RegisterWorker(); #if CPU_BOUND_LOAD Thread.SpinWait(5000000); // CPU-bound load #else Thread.Sleep(10); // I/O-bound load #endif } Console.WriteLine("<--Action({0}, #{1:00})", targ, tid); }, i); } int delay = 50; do { int till = Environment.TickCount + delay; do { if (Console.KeyAvailable) { goto Exit; } Thread.Sleep(15); } while (Environment.TickCount < till); delay += 50; // // Comment the next statement to allow worker thread retirement! // /* * ThreadPool.QueueUserWorkItem(_ => { * WorkerThreadReport.RegisterWorker(); * Console.WriteLine("ExtraAction() --><-- on worker thread #{0}", Thread.CurrentThread.ManagedThreadId); * }); */ } while (true); Exit: Console.WriteLine("-- {0} worker threads were injected", WorkerThreadReport.CreatedThreads); WorkerThreadReport.ShowThreads(); WorkerThreadReport.ShutdownWorkerThreadReport(); }