.NET Framework 4.0 Task Parallell Library vs. the Concurrency and Coordination Runtime

Introduction

I really love Concurrency and Coordination Runtime (CCR) and I have a major product built around CCR. Ever since the .NET Framework 4.0 Task Parallel Library (TPL) was released, I’ve been contemplating moving off of CCR.

There are some compelling reasons to consider adopting TPL over CCR. For example, TPL is part of the .NET Framework and some tools in Microsoft Visual Studio center around TPL. Therefore, standardizing on the new patterns and practices supported by the .NET Framework and Visual Studio may be better than adopting a product unknown to the typical .NET developer. CCR may also be overkill if a developer simply wants to handle some asynchronous work.

Unfortunately, choosing between adopting CCR and building what you need from TPL is not easy. CCR and TPL are not symmetrical solutions. TPL is much more granular and general. CCR is tailored to solving coordination problems typically encountered in Robotics.

However, many of the TPL patterns fit somewhere inside of CCR. So, a logical way to do a TPL to CCR comparison is to replace a segment of CCR functionally with TPL code. Using some prototype sample code I developed to understand where TPL patterns fit within CCR, I’m going to walk through how I replaced a segment of CCR functionality with TPL code.

Constraints and Caveats

Before reviewing the code, there are some facts that I need to clarify.

First, I don’t know CCR internals. The prototype mimics some of the CCR behavior, but I have no access to the CCR source code, so I don’t know if the behavior is accurate. The sample focuses more on replacing functionality, but not on accurately replacing functionality. So, for example, performance may be better or worse with equivalent TPL functionality.

Also, the prototype is not CCR feature complete. I limited the scope to the Receiver Arbiter functionality. I did not review things like Choice, Interleave, and MultiplePortReceive Arbiters. Suspending and Creation CCR functionality was not part of the sample either. I also did nothing to handle exceptions.

This article does assume some familiarity with CCR. A complete introduction to CCR is beyond the scope of this article, but you’ll find helpful resources at the end of the article.

Finally, the goal of this article was to look at where TPL fit into CCR and then, extrapolate from the conversion experience to determine whether I could replace CCR with TPL parts. This article is only a starting point for a developer’s evaluation. There are no simple answers in this article.

With these facts in mind, I’ll begin with an overview of the sample code.

Sample Overview

I took a sample from a prior article, Extending Microsoft’s Concurrency and Coordination Runtime with MSMQ and replaced what the CCR was doing with an assembly built from TPL classes mimicking CCR functionality. Here is a summary of the major classes I replaced with equivalent TPL based classes:


  • Port – In CCR, the Port serves as a conduit into CCR. Port is a generic class tied to the class carrying the message payload into CCR. The message payload is a class containing the delegate function and accompanying data.
  • Arbiter – An Arbiter handles Port activation and dictates the coordination pattern with CCR. As I stated earlier, I limited the sample code to the Receiver Arbiter. Arbiters also tie DispatcherQueues to a Port.
  • Dispatcher – The Dispatcher pulls messages from DispatcherQueues , and executes the payload on a set of Threads allocated inside of the Dispatcher.

After creating the TPL based assembly I removed all reference to CCR and ran the sample using the TPL assembly. The execution flow mirrors that of CCR. The graphic below depicts execution.



Figure 1: TPL and CCR execution. Source: PDC 2008

I’ll review each class in more detail starting with the Port class.

Port<T>

Below is the Port class implementation from the sample.


public class Port<T>
{
   internal Handler<T> Handler { get; set; }
   internal DispatcherQueue Queue { get; set; }

   public void Post(T classRef)
   {
       var invoke = new InvokeT<T>(Handler, classRef);

       this.Queue.Enqueue(invoke);
   }

}


Most of the class functionality centers on packaging the delegate and accompanying data so other parts of the sample can execute the code. Like the CCR Port class, this implementation leverages generics.

Keeping with the CCR spirit, the public method “Post” initiates everything. Leveraging generics, Post is type safe. Internal functions hide code specific to the coordinating with the other classes, keeping the public interface clean.

IHandlerInvoker interface wraps execution and data together for consumption downstream. Most of the Port code does nothing with TPL. Like in CCR, this Port class works in conjunction with the Arbiter class.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read