public void InsertWorkItem(ThreadPoolWorkItem oWorkItem) { try { // Lock this object Monitor.Enter(this); // Add the work item to the queue queueInput.Enqueue(oWorkItem); if (isRunning && (queueInput.Count > hashThreads.Count) && (hashThreads.Count < maxThreadCount)) { // Create a thread to handle the new work item Thread th = new Thread(new System.Threading.ThreadStart(ThreadProc)); // Generate a thread name th.Name = Guid.NewGuid().ToString(); // Add the thread to the pool hashThreads.Add(th.Name, th); // Start the thread th.Start(); } } catch (Exception oBug) { // Store the exception lastException = oBug; } finally { // Unlock this obkect Monitor.Exit(this); } }
// Default exception handler, can be overriden private void OnThreadError(ThreadPoolWorkItem oWorkItem, Exception oError) { if (oWorkItem == null) { lastException = oError; } else { oWorkItem.lastException = oError; } }
private void ThreadProc() { // While we're runing while (isRunning) { object obj = null; // Lock this object Monitor.Enter(this); // See if there's something in the queue if (queueInput.Count > 0) { // Get work item out of the queue obj = queueInput.Dequeue(); } // Unlock this object Monitor.Exit(this); // Do we have a work item if (obj == null) { // Nothing to do bool bQuit = false; // Lock this object Monitor.Enter(this); // If we're running above the min thread count, remove the thread if (hashThreads.Count > minThreadCount) { // Remove the thread from the pool hashThreads.Remove(Thread.CurrentThread.Name); // Quit thread loop bQuit = true; } // Unlock this object Monitor.Exit(this); // See if we're done if (bQuit) { // Done return; } } else { // We have an item of work to do ThreadPoolWorkItem oWorkItem = (ThreadPoolWorkItem)obj; try { // Execute the method on the work item oWorkItem.objOutput = oWorkItem.delegateToCall(oWorkItem.objInput); } catch (Exception ex) { // See if we have an exception delegate to call if (ThreadError != null) { // Call the thread delegate, this may throw an exception by design ThreadError(oWorkItem, ex); } } if (oWorkItem.storeOutput) { // Lock this object Monitor.Enter(queueOutput); // Add the competed item to the output queue queueOutput.Enqueue(oWorkItem); // Unlock this object Monitor.Exit(queueOutput); } } // Don't run again for server pause seconds Thread.Sleep((int)(1000 * serverPauseSeconds)); } }