46

Im using Generic.Queue in C# 3.0 and Monitor.Enter,wait,exit for wait before consuming the queue (wait for the element to be enqueued). Now im moving to C# 4.

Can anyone suggest me which one is fast and best especially to avoid locks..

BlockingCollection vs concurrentQueue or any thing else...

Note. I dont want to restrict my producer

Thanks in advance..

Christopher Creutzig
  • 8,656
  • 35
  • 45
C-va
  • 2,910
  • 4
  • 27
  • 42

1 Answers1

117

BlockingCollection and ConcurrentQueue are there for precisely this reason. I doubt that you'll find anything better, or simpler to use. The parallel extensions team know their stuff :)

Just a quick check on versions though - you're definitely using .NET 4, not just C# 4? (For example, you could be using Visual Studio 2010 and thus C# 4, but still targeting .NET 3.5, in which case you couldn't use Parallel Extensions.)

You may also want to start researching Task-Based Asynchronous Pattern, TPL Dataflow and the async/await features of C# 5... obviously you can't use them just yet, but it doesn't hurt to know what's coming up.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    BlockingCollection and ConcurrentQueue which one is fast and best – C-va Feb 15 '11 at 08:11
  • 7
    @MSK: You create a `ConcurrentQueue` and then wrap it in a `BlockingCollection` which coordinates the Add/Take methods. (You then let it manage the queue completely - you shouldn't touch the ConcurrentQueue directly yourself afterwards.) – Jon Skeet Feb 15 '11 at 08:13
  • Thank u.. Pls suggest me BlockingCollection/ConcurrentQueue which one is fast and best – C-va Feb 15 '11 at 08:13
  • 28
    @MSK: Did you actually *read* my comment? *You use the two types together.* Create a `ConcurrentQueue`, and then create a `BlockingCollection` to wrap it. Then use the `BlockingCollection` exclusively. (In fact, if you just create a BlockingCollection without passing anything to the constructor, it will create a ConcurrentQueue for you, but you ought to understand what's going on.) – Jon Skeet Feb 15 '11 at 08:16
  • 3
    @MSK: I don't know what more to tell you really... I've told you how to do it twice. Have you read the docs for BlockingCollection, and the example in there? – Jon Skeet Feb 16 '11 at 10:26
  • @jon : BlockingCollection bc = new BlockingCollection(); Task t1 = Task.Factory.StartNew(() => { bc.Add(1); bc.Add(2); bc.Add(3); bc.CompleteAdding(); }); Task t2 = Task.Factory.StartNew(() => { try { while (true) Console.WriteLine(bc.Take()); } } }); – C-va Feb 16 '11 at 12:03
  • @ jon :In the above code, Will the Take() waits if the queue is empty and resumes to dequeue autmatically if new item is added (without using wait/signal). Or i have ot use monitor.wai,pulseall / ManualResetEvent ? – C-va Feb 16 '11 at 12:04
  • 2
    @MSK: What does the documentation for BlockingCollection.Take say? (You might also want to look at BlockingCollection.GetConsumingEnumerable()). – Jon Skeet Feb 16 '11 at 12:06
  • @jon : Takes an item from the BlockingCollection. A call to Take may block until an item is available to be removed. – C-va Feb 16 '11 at 12:09
  • 2
    @MSK: Exactly. So if the queue is empty, it will block until there's an item in the queue. The whole point of using the type is to avoid you having to use Wait etc. – Jon Skeet Feb 16 '11 at 12:11
  • 1
    @jon : I had a little bit of confusion that will it resumes or not. Thats why the repetition in my Question. K . Now im Clear. Thanks a lot. – C-va Feb 16 '11 at 12:21
  • 7
    One point about ConcurrentQueue that I've just run into with a Pro/Con implementation... http://blogs.msdn.com/b/pfxteam/archive/2012/05/08/concurrentqueue-lt-t-gt-holding-on-to-a-few-dequeued-elements.aspx No biggie if the items are small... a significant problem if they are large objects (like mine are) – Dave Lawrence Oct 11 '12 at 07:31
  • 1
    I would +10 this post if I could, I really mean it! BTW, a `BlockingCollection` can be iterated using a `Parallel.For`, which is similar in utility to a PCQ, and possibly a bit easier (maybe a LOT easier) to whip up the code for. – code4life May 08 '13 at 03:03
  • 6
    BlockingCollection wraps ConcurrentQueue by default - http://msdn.microsoft.com/en-us/library/dd267312(v=vs.110).aspx – jjxtra Jul 02 '14 at 15:52