11

I am developing a windows forms application ( c# ), and while program is running, it creates objects adds them to a list. I have to process the items in the list , with FIFO ( first in first out ). I want to do this in a backgroundthread and i have to process them in order, number 1 , number 2, number 3 and so on. And as soon as an item gets added to the list i want to process it. So i have to have something to check that list.

What is the best way to achieve this?

I know that blockingcollection does something similar, that it waits for an item to be added before processing it.

I can use a single thread with the Queue and just while(true) and take items if there is any?

What do you think?

syncis
  • 1,395
  • 4
  • 25
  • 43

2 Answers2

15

Sounds like you should go for the BlockingCollection<T> if you're planning on using a background thread. You can pretty easily do the same while(true) logic that you're looking for.

The BlockingCollection<T> gives you two important features

  1. It's thread-safe

  2. When you call Take(), it will block(i.e. wait until something is in the queue) for you, so you don't have to write any code with ManualResetEvents and the like, which is a nice simplification.

casperOne
  • 73,706
  • 19
  • 184
  • 253
Jonathan Beerhalter
  • 7,229
  • 16
  • 68
  • 78
  • Yes exactly ! I am just asking this to confirm my thought and if someome have a better idea :) – syncis Aug 23 '11 at 12:41
  • 2
    @Jonathan Beerhalter: Or, instead of calling `Take`, he could just have his background thread do a `foreach` on [`GetConsumingEnumerable`](http://msdn.microsoft.com/en-us/library/dd287186.aspx), which will yield the items as they are placed in the `BlockingCollection`. – casperOne Aug 23 '11 at 12:55
  • @syncis: `GetConsumingEnumerable` will block until an item is added to the `BlockingCollection` just like `Take` will; the thing is, what else is your background thread doing other than processing these items? If you are trying to save threads; don't, you are basically re-writing the thread pool and that's not generally a good idea. Note, more items can come in for `Take` or yielded through `GetConsumingEnumerable` while you are processing your items one by one (or you can send those items off to be processed in other threads, depending on your needs). – casperOne Aug 23 '11 at 13:12
0

IF you want to block if the queue is empty then use BlockingCollection - it is ideal... IF you want it more Queue-like (decide yourself how to deal with an empty) then ConcurrentQueue.

Both are thread-safe, in ConcurrentQueue most operations are implemented lock-free so really fast... either way use it directly or as the base type for your BlockingCollection for example BlockingCollection<string> = new BlockingCollection<string> (new ConcurrentQueue<string>) - you can even put a maximum capactiy on that (optional second param of constructor).

Yahia
  • 69,653
  • 9
  • 115
  • 144