4

I have a BlockingCollection that I m using in a classic publish-subscribe type example where the collection works as a buffer. When it reaches N it has to wait for the readers to consume at least one item. This works fine.

Now I would like to be able to reset the maximum number of items, the collection can hold, at runtime. I know how to use locks and monitors to achieve this and scrap the blockingcollection all together but I dont want to reimplement something that already exists in the core framework.

Is there any way to achieve that?

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Yannis
  • 6,047
  • 5
  • 43
  • 62
  • You are just creating the BlockingCollection with the Int ctor for it to hold N. Why not just new another BlockingCollection at run time? – paparazzo Jun 30 '13 at 19:28
  • Cause at that time the BlockingCollection will be (potentially) full with elements. If I wanted to increase/decrease the size I would have to empty it (or wait for all elements to be consumed) and the re-instantiate it. – Yannis Jun 30 '13 at 19:35
  • 1
    There is no way to achieve this with the .NET class. Throwing it away is the only real option. Very hard to do btw, a thread could be buried inside a Take() call and never return. The odds you'll invoke deadlock should be quite high. – Hans Passant Jun 30 '13 at 20:22
  • No you don't have to re-instantiate IT nor wait for IT to clear. You can create a new one of the proper size and start adding to it. You could even have the consumer side of the new not consume until the prior cleared. – paparazzo Jun 30 '13 at 20:54
  • Can you get away with using two BlockingCollections, the queue you already use for consumers to wait on and a pool queue for the producer to wait on? If you initially fill the pool with N objects, that limits the number of objects in the queues to N without setting an atificially low max size. To 'increase buffer size', just add some more objects to the pool. To 'reduce buffer size', get objects from the pool and allow them to be disposed. – Martin James Jul 01 '13 at 05:07
  • @Blam its the "until the prior has cleared" that's the issue here. But I like your idea. I could have one blocking collection and when I need to increase / decrease the size I create a new one and dispose of the old one. Then the new one is used. But the old one should be emptied first – Yannis Jul 01 '13 at 08:25
  • What is the issue with "until the prior has cleared"? – paparazzo Jul 01 '13 at 12:34
  • How do you check that the old BlockingCollection has cleared? Do you wait for all its items to be consumed first? And if so how (whats the optimum solution). Stop accepting new items on the old one and accept new ones on the new one? Consume the old one first before accepting any new items? And how to check if all items have been consumed? have a monitor.wait and a monitor.pulse? Have a loop with a sleep in? – Yannis Jul 01 '13 at 13:23
  • Check the documentation. catch (InvalidOperationException) for when the old cleared. See my original comment for the other questions. – paparazzo Jul 01 '13 at 14:05

0 Answers0