using System; using System.Threading; using System.Collections; namespace SomeNamespace { public delegate void ThreadActivationCallback() ; public delegate void JobFinishCallback ( object state ) ; public delegate bool OnErrorCallback ( Exception exc ) ; public class CustomThreadPool { public event ThreadStart ThreadStarted ; public event ThreadStart ThreadFinished ; public event WaitCallback JobStarted ; public event WaitCallback JobFinished ; public event OnErrorCallback OnError ; public event ThreadStart Idle ; public uint MaxThreads ; internal int activeThreads = 0 ; internal Stack workItems ; internal int threadTimeout = 30000; // 30 seconds private Timer timer ; public readonly string Name ; public ClalThreadPool ( string name , uint maxThreads ) { Name = name ; MaxThreads = maxThreads; workItems = Stack.Synchronized ( new Stack( (int) ( 10 * maxThreads ))) ; timer = new Timer ( new TimerCallback ( OnTimer ) , null , 0 , 1000 ) ; } public bool QueueUserWorkItem ( WaitCallback callback , object state ) { if ( callback == null ) return false ; lock ( this ) { workItems.Push ( new WorkItem ( callback , state )) ; if ( activeThreads == 0 ) WorkThread.AddWorker ( this ) ; return true; } } public void OnTimer ( object state ) { lock ( this ) { if ( workItems.Count ==0 ) return ; if ( activeThreads < MaxThreads ) WorkThread.AddWorker ( this ) ; } } internal void ThreadStartedEvent() { if( ThreadStarted != null ) ThreadStarted() ; } internal void ThreadFinishedEvent() { if ( ThreadFinished != null ) ThreadFinished() ; } internal void JobStartedEvent( object parameter ) { if ( JobStarted != null ) JobStarted ( parameter ) ; } internal void JobFinishedEvent ( object parameter ) { if ( JobFinished != null ) JobFinished ( parameter ) ; } internal void IdleEvent () { if ( Idle != null ) Idle () ; } internal bool OnErrorEvent ( Exception exc ) { if ( OnError != null ) return OnError ( exc ) ; return false ; } public void Stop() { lock ( this ) { timer.Change ( Timeout.Infinite , Timeout.Infinite ) ; workItems.Clear() ; MaxThreads = 0 ; } } } internal class WorkItem { public object parameter ; public WaitCallback callback ; public WorkItem ( WaitCallback callback , object state ) { this.parameter = state ; this.callback = callback ; } } internal class WorkThread { CustomThreadPool pool ; internal WorkThread ( CustomThreadPool pool ) { this.pool = pool ; } static public void AddWorker ( ClalThreadPool pool ) { Interlocked.Increment ( ref pool.activeThreads ) ; WorkThread worker = new WorkThread ( pool ) ; Thread thread = new Thread ( new ThreadStart ( worker.Loop )) ; thread.Start() ; } private void Loop() { try { pool.ThreadStartedEvent() ; while ( true ) { WorkItem item = null; try { item = (WorkItem) pool.workItems.Pop() ; } catch { Thread.Sleep ( pool.threadTimeout ) ; item = (WorkItem) pool.workItems.Pop() ; if ( item == null ) break ; } try { pool.JobStartedEvent ( item.parameter ) ; item.callback ( item.parameter ) ; pool.JobFinishedEvent ( item.parameter ) ; } catch(Exception exc) { try { pool.OnErrorEvent ( exc ) ; } catch ( Exception critical ) { // Check for critical exception -- pseudo code if( critical is CRITICAL) throw ext; } } if ( pool.activeThreads > pool.MaxThreads ) return; } } catch{} finally { Interlocked.Decrement ( ref pool.activeThreads ) ; } pool.ThreadFinishedEvent() ; if ( pool.activeThreads == 0 ) pool.IdleEvent(); } } }