.NET Framework: Task Parallel Library Dataflow | CodeGuru

.NET Framework: Task Parallel Library Dataflow

Introduction Coupled to the new C# Async Community Technology Preview released during PDC 2010; is a library called Task Parallel Library Dataflow (TDF). TDF is part of a growing list of technologies built on top of the Task Parallel Library (TPL) that are part of Microsoft’s Technical Computing Initiative. Like many of the other Technical […]

Written By
CodeGuru Staff
CodeGuru Staff
Mar 10, 2011
2 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

Introduction

Coupled to the new C# Async Community Technology Preview released during PDC 2010; is a library called Task Parallel Library Dataflow (TDF). TDF is part of a growing list of technologies built on top of the Task Parallel Library (TPL) that are part of Microsoft’s Technical Computing Initiative. Like many of the other Technical Computing products TDF aims to make Parallel Computing products and patterns more accessible to the Microsoft Development Community.

Like other Technical Computing products TDF builds on proven industry patterns and practices. TDF couples the Task Parallel Library to a set of classes/interfaces that leverage Message Passing to coordinate the behavior of a solution. Using a short sample application I’ll demonstrate how to apply TDF.

Overview

You can download TDF from the Dataflow site http://msdn.microsoft.com/en-us/devlabs/gg585582.

Note: While I think it’s important to study new products and patterns coming down the pipeline I would never use a CTP in a production application. Please remember that TDF is not a “production” grade release.

According to the TDF documentation, TDF’s architecture gains it’s inspiration from a number of different sources. Among the sources is the Concurrency and Coordination Runtime (CCR). TDF is a new product in CTP so there are no clear guidelines on where and when to use TDF. Good TDF candidates would likely be applications that benefit from the composition and decoupling you get with messaging and the execution benefits of TPL. So, for example, intensive workload applications like the ones you find inside of a Windows Service.

TDF is composed of a set of “Blocks“. Blocks receive, send, or both receive and send messages to other Blocks. In general, the pattern for a block looks a lot like the graphic below.

Block Architecture, Source:
Figure 1: Block Architecture, Source: “An Introduction to TPL Dataflow

TDF Messages are instances of the class the particular block is configured to interact with. Messages are stored in TPL data structures.

Blocks leverage Tasks. I think of task classes as chunks of work. Blocks run tasks on a given TaskScheduler. Each Block exhibits different behavior in how it dispatches to the TaskScheduler and/or how it handles messages.

Some concrete examples will demonstrate how a few of these blocks work.

Advertisement

Sample Overview

The full sample code appears below.

  using System.Threading.Tasks.Dataflow;
  using System.Threading.Tasks;
  using System.Threading;

  namespace TPL.Test.DataFlows
  {
      class Program
      {
          static void Main(string[] args)
          {
              var writeOut = new ActionBlock<string>(s =>
              {
                  Console.WriteLine(s);
              }

              );


              var broadcast = new BroadcastBlock<string>(s => s.ToString());

              var transform = new TransformBlock<string, string>(s => s.ToUpper());

              var buffer = new BufferBlock<DateTime>();

              var join = new JoinBlock<string, DateTime>();

              var joinWrite = new ActionBlock<Tuple<string, DateTime>>(t => writeOut.Post(t.Item1 + " at " + t.Item2.ToString()));


              broadcast.LinkTo(transform);

              broadcast.LinkTo(writeOut);

              transform.LinkTo(join.Target1);

              buffer.LinkTo(join.Target2);

              join.LinkTo(joinWrite);


              //Begin activating everything

              Task.Factory.StartNew(() =>
              {
                  while (true)
                  {
                      Thread.Sleep(2000);
                      buffer.Post(

                      DateTime.Now);
                  }                
              },

              TaskCreationOptions.LongRunning);

              var itr = 0;

              while (itr < 15)
              {
                  broadcast.Post(

                  "New string " + Guid.NewGuid().ToString());

                  Thread.Sleep(1000);
                  ++itr;
              }

              Console.WriteLine("Execution complete, any key to continue...");
              Console.ReadKey();
          }
      }
  }
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.