September 2, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Create Your Own Thread Pool

  • November 10, 2008
  • By Chris Bennett
  • Send Email »
  • More Articles »

The last critical method in the MyThreadPool class is the ManagementWorker as listed below.

private void ManagementWorker()
{
   while (KeepManagementThreadRunning)
   {
      try
      {
         //Check to see if we have idle thread we should free up
         if (ThreadList.Count > m_MinThreads)
         {
            foreach (WorkThread wt in ThreadList)
            {
               if (DateTime.Now.Subtract(wt.LastOperation).Seconds
                  > m_IdleTimeThreshold)
               {
                  wt.ShutDown();
                  lock (ThreadList)
                  {
                     ThreadList.Remove(wt); break;
                  }
               }
            }
         }
      }
      catch { }

      try
      {
         Thread.Sleep(1000);
      }
      catch { }
   }
}

The ManagementWorker is used to manage the thread pool and to shut down idle threads in the ThreadList. It first ensures you have the minimum number of threads. Then, it checks to see whether the thread has been idle long enough to be shut down. Although it may have been possible to have each worker thread perform the necessary checks, it is far easier to manage the list from a central point. However, it also means that each instance of MyThreadPool will have the overhead of a separate management thread.

WorkThread class

The last class in the thread pool is the WorkThread. The critical method in the WorkThread class is Worker, listed below:

private void Worker()
{
   WorkItem wi;
   while (m_KeepRunning)
   {
      try
      {
         while (m_WorkQueue.Count > 0)
         {
            wi = null;
            lock (m_WorkQueue)
            {
               wi = m_WorkQueue.Dequeue();
            }
            if (wi != null)
            {
               m_LastOperation = DateTime.Now;
               m_Busy = true;
               wi.Delegate.Invoke(wi.WorkObject);
            }
         }
      }
      catch { }

      try
      {
         m_Busy = false;
         Thread.Sleep(1000);
      }
      catch { }
   }
}

The Worker method is at the heart of the ThreadPool; it continuously pulls items from the WorkQueue and performs the actual work. Essentially, the method checks the queue once per second. In the event that items are in the queue, it will process items in the queue until the queue has been exhausted. To perform the work, the method executes each delegate from the WorkItem class above. The method passes the WorkObject from the WorkItem class to the delegate method.

Testing the ThreadPool

With all of the classes built, it is fairly easy to create a simple console app to test the thread pool. The test application is listed below:

static void Main(string[] args)
{
   MyThreadPool tp = new MyThreadPool();

   for (int i = 0; i < 100; i++)
   {
      tp.QueueWork(i, new WorkDelegate(PerformWork));
   }

   Console.ReadLine();
   tp.Shutdown();
}

static private void PerformWork(object o)
{
   int i = (int)o;
   Console.WriteLine("Work Performed: " + i.ToString());
   System.Threading.Thread.Sleep(1000);
   Console.WriteLine("End Work Performed: " + i.ToString());
}

The main method above first creates an instance of the MyThreadPool class. Then, it adds 100 work items into the queue of the thread pool. To ensure the console application continues to run after queueing up the work, it uses the Console.ReadLine() to pause the main thread. For the test, the PerfomWork method writes a couple of lines to the console and tells the thread to sleep for 1 to simulate a second of work. The output of the application should look like the following image:

Figure 1: The Console Application

You now have all of the components needed to create multiple thread pools in your application using the above classes.





Page 2 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel