Concurrent producer consumer pattern using C# 4.0, BlockingCollection & Tasks

Here is a very simple illustrative and annotated producer consumer pattern example using C#, .NET 4.0, BlockingCollection and Tasks. The example sets up one producer thread on which it produces 100 integers and two consumer threads which each read that data off a common concurrent blocking queue. Although I use a BlockingCollection here it is backed internally by a concurrent queue.

[csharp]
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;

namespace test
{

class Program
{

static void Main(string[] args)
{

Console.WriteLine();

// declare blocking collection backed by concurrent queue
BlockingCollection<int> b = new BlockingCollection<int>();

// start consumer 1 which waits for data until available
var consumer1 = Task.Factory.StartNew(() =>
{
foreach (int data in b.GetConsumingEnumerable())
{
Console.Write("c1=" + data + ", ");
}
});

// start consumer 2 which waits for data until available
var consumer2 = Task.Factory.StartNew(() =>
{
foreach (int data in b.GetConsumingEnumerable())
{
Console.Write("c2=" + data + ", ");
}
});

// produce 100 integers on a producer thread
var producer = Task.Factory.StartNew(() =>
{
for (int i = 0; i < 100; i++)
{
b.Add(i);
}
b.CompleteAdding();
});

// wait for producer to finish producing
producer.Wait();

// wait for all consumers to finish consuming
Task.WaitAll(consumer1, consumer2);

Console.WriteLine();
Console.WriteLine();

}

}

}
[/csharp]

The output from running the program above is as follows. It’s basically consumer 1 and 2 interleaving as they read integers off the queue as they’re being produced.

c1=0, c1=2, c1=3, c1=4, c1=5, c1=6, c1=7, c1=8, c1=9, c1=10, c1=11, c1=12, c1=13, c1=14, c1=15, c1=16, c1=17, c1=18, c1=19, c2=1, c2=21, c2=22, c2=23, c2=24, c2
=25, c2=26, c2=27, c2=28, c2=29, c2=30, c2=31, c2=32, c2=33, c2=34, c2=35, c2=36, c2=37, c2=38, c2=39, c2=40, c2=41, c2=42, c2=43, c2=44, c2=45, c2=46, c2=47, c
2=48, c2=49, c2=50, c2=51, c2=52, c2=53, c2=54, c2=55, c2=56, c2=57, c2=58, c2=59, c2=60, c2=61, c2=62, c2=63, c2=64, c2=65, c2=66, c2=67, c2=68, c2=69, c2=70,
c2=71, c2=72, c2=73, c2=74, c2=75, c2=76, c2=77, c2=78, c2=79, c2=80, c2=81, c2=82, c2=83, c2=84, c2=85, c2=86, c2=87, c2=88, c2=89, c2=90, c2=91, c2=92, c2=93,
 c2=94, c2=95, c2=96, c2=97, c2=98, c2=99, c1=20,

It’s somewhat sad and disheartening to see just how much further ahead C# is of Java in terms of the expressiveness and richness of the language. I personally really enjoyed using the lambdas above and I hope that with Java 8 the SDK libraries will grow to develop a more fluid and expressive style.

Credit: [1, 2]

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s