Ayende @ Wiki

Threads are complex, and Rhino Commons is here to try to help. The library contains several interesting classes with regards to threads: RhinoThreadPool, ThreadSafeQueue, CountdownLatch

Edit

RhinoThreadPool

The RhinoThreadPool allows you to:
  • Cancel pending work or abort executing threads safely
  • Wait for work in the thread pool to be completed
  • Events for starting and finishing work items

Basic usage is similar to the usual thread pool:

RhinoThreadPool.QueueUserWorkItem(new WaitCallback(MyCallback), myState);


But once you started on that, you can do more interesting things with it.

WorkItem workItem = RhinoThreadPool.QueueUserWorkItem(new WaitCallback(MyCallback), myState);
// at a later time
workItem.Cancelled = true;//will prevent it from running if it is not already running
// or this, which allows you to get its state 
WorkItemStatus status = RhinoThreadPool.Cancel(workItem, false);
// and optionally abort the work item execution if needed
WorkItemStatus status = RhinoThreadPool.Cancel(workItem, true);


You can also register work and wait for it:
for(int i=0;i<100;i++)
{
   RhinoThreadPool.QueueUserWorkItem(new WaitCallback(Foo), i);
}
RhinoThreadPool.WaitForAllThreadsToFinish();


Edit

Events:



When work item begins to run:

RhinoThreadPool.WorkStarted += delegate(WorkItem item)
{
   Console.WriteLine(item.State+" started");
}


When work item finishes to run, including abnormally:

RhinoThreadPool.WorkFinished += delegate(WorkItem item)
{
   Console.WriteLine(item.State+" started");
}


Edit

Exceptions:

Important: RhinoThreadPool doesn't try to catch exceptions, if a user work item callback has thrown an exception, it will be propagate to the default .NET handling of unhandled thread exception, and will usually terminate the application.

Edit

Thread Safe Queue

As the name implies, it allows to Enqueue() and Dequeue() in a thread safe manner. Trying to Dequeue from an empty queue will block, until there is data to return. To call the queue without blocking, use TryDequeue()

Edit

Countdown Latch

A simple lock implementation that allows a producer to wait for a set of consumer to finish their work, here is a simple test that demonstrate its usage:

 Test
 public void WaitForEventToRun()
 {
     int count = 5000;
     CountdownLatch countdown = new CountdownLatch(count);
     bool">count"> done = new bool[count;
     for (int i = 0; i < count; i++)
     {
         int j = i;
         ThreadPool.QueueUserWorkItem(delegate
         {
             donej = true;
             countdown.Set();
         });
     }
     bool result = countdown.WaitOne();
     Assert.IsTrue(result);
     for (int i = 0; i < count; i++)
     {
         Assert.IsTrue(donei, "{0} was not set to true", i);
     }
 }

ScrewTurn Wiki version 2.0 Beta. Some of the icons created by FamFamFam.