4

I have many threads that can add items to collection and remove specific items from that collection on some condition. In first project, readers more than writers. In second project, readers may be more than writers or equal or less.

  1. How I should manage add/remove to that collection?
  2. What collection to use? Simple List with blocking on add/remove?
  3. Which blocking mechanism to use(lock, ReaderWriterLockSlim,...)?
theateist
  • 13,879
  • 17
  • 69
  • 109

2 Answers2

0

You can use data structures from namespace System.Collections.Concurrent. They encapsulate all three aspects you mentioned and can be used from concurrent threads without explicit locking.

See: System.Collections.Concurrent Namespace at MSDN

For example ConcurrentBag<T> has ICollection interface and is a thread-safe implementation, optimized for scenarios where the same thread will be both producing and consuming data stored in the bag.

If you need quick object lookup you might also use ConcurrentDictionary<TKey, TValue>.

George Mamaladze
  • 7,593
  • 2
  • 36
  • 52
  • 2
    But how I can remove specific item(with `List I can do `myList.Remove(myObj)`? How I can do it with some of **Concurrent Collection**? – theateist Jun 05 '12 at 06:19
  • `TryTake` - Attempts to remove and return an object from the `ConcurrentBag`. It is called TryTake not Remove because you are not guaranteed that the object is still there. Some other thread might have removed it already. – George Mamaladze Jun 05 '12 at 06:41
  • 3
    but it **DOES NOT** return me specific item. Assume I have `myObj` in `Concurrent Collection` and I want to take that `myObj` item and not any item. How can I do it? – theateist Jun 05 '12 at 06:45
  • You can enumerate through all objects looking for one you need or alternatively if you need quick object lookup you might also use `ConcurrentDictionary`. – George Mamaladze Jun 05 '12 at 06:56
  • Won't it be more simple if I'll use simple 'List' and when I want to add or remove I'll use `lock` on it? This will give exactly what I need, right? – theateist Jun 05 '12 at 07:10
  • Yes you can go on and implement your own locking on list, but it's a bit more than just setting lock around every add or remove operation. For instance avoiding deadlocks is one of most easily overlooked aspect. Also you can use manual locking if you have only one place in your application, but as I understand you have multiple usages. In this case encapsulation makes sense to avoid code and effort duplication. – George Mamaladze Jun 05 '12 at 07:22
  • I agree that Concurrent collections are the way to go, unless you have a specific need to be sure that when Reader R looks at the collection at a given time, that the collection is not modified concurrently. If I wanted to find the Average of a list of numbers at exactly 3:05 p.m., explicit locking would be necessary so the reader doesn't get newer info inserted into the collection. It will not be simpler to manually use locks than to use the built-in concurrent collections. – Xantix Jun 23 '12 at 08:16
-2

ConcurrentBag is unable to remove a specific item cause of it's a bug with unordered collection of objects.

But BlockingCollection has the ability to do this with using TryTake method. Just pass the item you want to remove as the parameter. See: http://msdn.microsoft.com/en-us/library/dd287184(v=vs.110).aspx

iou90
  • 257
  • 3
  • 9
  • 1
    Rather than just giving the link, post at least a snippet or example from it in case it ever goes dead. – Illidanek Jul 03 '14 at 10:03
  • 3
    In Blocking Collection you can only remove items from the start or end, not from anywhere inside the collection. – Purusartha Apr 23 '15 at 06:24
  • 2
    You cannot remove a specific item. The item-Parameter is marked as an out-parameter! – CSharpie Nov 27 '15 at 11:09
  • 1
    You don't pass the item you want to remove to `TryTake`, you pass an `out` parameter that is set to the next available item's value if it was successful. It's the same as `ConcurrentBag.TryTake`. – Rufus L Jun 07 '19 at 18:24