Posted By: Phil Pennington | Oct 29th @ 2:22 PM | 31,991 Views | 13 Comments
Join Josh and Steve as they demonstrate how to use the new .NET4 BlockingCollection<T> class in class Producer/Consumer parallel computing scenarios.

BlockingCollection<T> is one of many new thread-safe data-structures available with .NET4 and Visual Studio 2010.

Learn more about the System.Collections.Concurrent namespace and keep abreast of Parallel Computing tools and techniques via the Concurrency Dev Center.

See all videos in this series.


Rating:
4
0
aL_
aL_
Rx ftw

so does the concurrent collection remove values after they've been retrived?

if you dont want multiple consumers to process the same data, thats a good thing, but what if you do? like in a logger for instance, the app produces a bunch of messages, all the consumers want all the messages, and maybe a while after they've been produced. there migt be a log window in the app, but also a remote monitoring app for example

 

how would you go about solving that?

re: does the concurrent collection remove values after they've been retrieved?

 

If you just do:

        foreach(var item in blockingCollection) { ... }

you'll be enumerating the contents without removing the values.  If you do:

        foreach(var item in blockingCollection.GetConsumingEnumerable()) { ... }

then you'll be enumerating the contents and removing the values as you do.

Why does BlockingCollection<T> not expose an event for the consumer?

GrantB
GrantB
What the hell are we supposed to use man? Harsh language?

If I have multiple producers and one of them calls bc.CompleteAdding() wouldn't it be possible for the consumer to exit before the other consumers have finished their bc.Add() calls? Am I misunderstanding the behavior?

 

 

AdamSpeight2008
AdamSpeight2008
The Bandito Coder

Just a minor thing, you said "all Five are output" but in the Console window there are only 4.   Doh!

I was just about to ask the same thing Smiley

staceyw
staceyw
Before C# there was darkness...

"If I have multiple producers and one of them calls bc.CompleteAdding() wouldn't it be possible for the consumer to exit before the other consumers have finished their bc.Add() calls? Am I misunderstanding the behavior?"

 

If you call CompleteAdding(), any more calls to Add() will throw.  Consumers will run until q empty and will throw on Take().  For multiple producers, you probably need a master that can signal producers to stop and then master can exit clean with a CompleteAdding.  Consumers can catch the cancel exception or use TryTake.  For that matter, the producers could use TryAdd as well.  Then other producers could exit cleanly and you may not need an out-of-band signal in that case.

re: "you said "all Five are output" but in the Console window there are only 4.   Doh!"

 

It actually did output all five.  Unfortunately the screen capture software appears to only have been taking appx one image per second, and it didn't take a snapshot between the time that the consumer output its fourth value and the time that the console window closed... in that time window the 5th element did appear.  You can visibly see this delay in several other portions of the video, such as when I'm typing (and portions of words are magically appearing in chunks Wink) or when dragging around the console window.

For multiple producers where you want to call complete adding when they're all done, TPL's coordination constructs can come in very handy.  e.g. I can use a ContinueWhenAll to call CompleteAdding:

 

var bc = new BlockingCollection<int>();

var producers = new List<Task>();

for(int i=0; i<numProducers; i++)

{

    producers.Add(Task.Factory.StartNew(() => /* produce data to bc here */));

}

Task.Factory.ContinueWhenAll(producers.ToArray(), _ => bc.CompleteAdding());

Microsoft Communities