I have the following code to help my understanding of multiple threading, the purpose of it is to create 3 background worker threads with debug code to display thread usage/availablity. Now code seems ok from what I can see but I sometimes get unexpected results.
Calling Code :
static void Main(string[] args) { ThreadPool.CreatWorkBetter(); Console.ReadLine(); } Implementation Code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using t = System.Threading; namespace CSharpConcepts { public static class ThreadPool { private static t.ManualResetEvent[] resetEvent; public static void CreatWorkBetter() { Console.WriteLine("Start"); ListAvailableThreads(); resetEvent = new t.ManualResetEvent[3]; resetEvent[0] = new t.ManualResetEvent(false); resetEvent[1] = new t.ManualResetEvent(false); resetEvent[2] = new t.ManualResetEvent(false); t.ThreadPool.QueueUserWorkItem( new t.WaitCallback(delegate(object state) { PooledFunc("Stage 1", resetEvent[0]); })); t.ThreadPool.QueueUserWorkItem( new t.WaitCallback(delegate(object state) { PooledFunc("Stage 2", resetEvent[1]); })); t.ThreadPool.QueueUserWorkItem( new t.WaitCallback(delegate(object state) { PooledFunc("Stage 3", resetEvent[2]); })); t.WaitHandle.WaitAll(resetEvent); Console.WriteLine("Finished"); ListAvailableThreads(); } static void PooledFunc(object state, t.ManualResetEvent e) { Console.WriteLine("Processing request '{0}'", (string)state); // Simulation of processing time t.Thread.Sleep(2000); Console.WriteLine("Request processed"); ListAvailableThreads(); e.Set(); } public static void ListAvailableThreads() { int avlThreads, avlToAsynThreads; t.ThreadPool.GetAvailableThreads(out avlThreads, out avlToAsynThreads); string message = string.Format("Processed request: {3}, From ThreadPool :{0} ,Thread Id :{1},Free Threads :{2}",t.Thread.CurrentThread.IsThreadPoolThread,t.Thread.CurrentThread.ManagedThreadId,avlThreads,t.Thread.CurrentThread.ThreadState); Console.WriteLine(message); } } } What I expect results wise is this and most of the time I get it( the critical line shown with free threads being back to 1023 is what I really want to see):
Start Processed request: Running, From ThreadPool :False ,Thread Id :1,Free Threads :1023 Processing request 'Stage 1' Processing request 'Stage 2' Processing request 'Stage 3' Request processed Processed request: Background, From ThreadPool :True ,Thread Id :4,Free Threads :1020 Request processed Processed request: Background, From ThreadPool :True ,Thread Id :3,Free Threads :1021 Request processed Processed request: Background, From ThreadPool :True ,Thread Id :5,Free Threads :1022 Finished Processed request: Running, From ThreadPool :False ,Thread Id :1,Free Threads :1023
However, I sometimes get with the free threads showing 1022, I would hope it's 1023 since 3 threads have completed the work so they should have been returned to the thread pool:
Start Processed request: Running, From ThreadPool :False ,Thread Id :1,Free Threads :1023 Processing request 'Stage 1' Processing request 'Stage 2' Processing request 'Stage 3' Request processed Processed request: Background, From ThreadPool :True ,Thread Id :3,Free Threads :1020 Request processed Processed request: Background, From ThreadPool :True ,Thread Id :4,Free Threads :1020 Request processed Processed request: Background, From ThreadPool :True ,Thread Id :5,Free Threads :1022 Finished Processed request: Running, From ThreadPool :False ,Thread Id :1,Free Threads :1022
Any ideas?