I got a chance to mess around with the Concurrency and Coordination Runtime (CCR) bits recently. Before I get into that, first check out this real-life code I wrote this week.
public static class NotificationQueue
{
private static Queue<Notification> _queue;
private static Semaphore _work;
static NotificationQueue()
{
_queue = new Queue<Notification>();
_work = new Semaphore(0, int.MaxValue);
}
public static void Enqueue(Notification n)
{
lock (_queue)
{
_queue.Enqueue(n);
}
_work.Release();
}
public static Notification Dequeue()
{
_work.WaitOne();
lock (_queue)
{
return _queue.Dequeue();
}
}
}
The idea here is to post notifications to the queue from many threads, and have a single notification thread sending the messages out from something like this:
private static void NotifyThreadProc()
{
while(!Abort())
NotificationQueue.Dequeue().Send();
}
The documentation for CCR is pretty sparse at this point, limited to just this paper, the Channel9 video, and this Wiki. Some of the particulars seem to have changed significantly, but I was able to figure out how to replicate my explicitly-threaded notification queue:
public class NotificationService : CcrServiceBase
{
private Port<Notification> _port;
public NotificationService()
: base(new DispatcherQueue("foo"))
{
_port = new Port<Notification>();
Activate(Arbiter.Receive(true, _port,
delegate(Notification n)
{
n.Send();
}));
}
public void Post(Notification n)
{
_port.Post(n);
}
}
That’s pretty awesome: notice that no explicit locks or waits are necessary, and I don’t need to write the NotificationThreadProc or the code required to start it. I just need to make a NotificationService and start posting to it.
I can’t say it’s the most immediately comprehensible API I’ve ever seen, but hopefully that will change with more documentation and some polish. It’s also possible that I am just warped from years of using the lower-level concepts. Overall this is awfully impressive for a library.