1

The new namespace System.Collections.Concurrent contains concurrent collections for dictionary, queue and stack among other classes. Anyone know why is it that there is no ConcurrentList?

UPDATE

I've posted a new question explaining my current scenario. I preferred that to changing the whole sense of the original question. Here's the link to the new question.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
Mike
  • 753
  • 1
  • 7
  • 16
  • 1
    Possible duplicate of [No ConcurrentList in .Net 4.0?](http://stackoverflow.com/questions/6601611/no-concurrentlistt-in-net-4-0) – stuartd Apr 28 '16 at 10:06

3 Answers3

6

If two threads added items simultaneously what expectation of 'order' would you have? ConcurrentBag is more appropriate if all you want is a collection of items.

Community
  • 1
  • 1
Ian Mercer
  • 38,490
  • 8
  • 97
  • 133
  • 2
    ConcurrentBag is *not* appropriate for general use. It's a very specialized class, used to provide quick thread-local storage and access. – Panagiotis Kanavos Feb 20 '15 at 08:38
5

Random access doesn't make much sense on a data structure that's changed from another thread.

If you look at the concurrent collections, you'll notice that their interface is specifically designed to work well with multi threaded access. I can't think of a useful list-like interface that works well with multithreaded code.

Random multi threaded access can make sense if the elements are never moved, but then you have an array.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • There are a variety of useful subsets of `IList` which could be implemented in thread-safe fashion. For example, one could have a collection which behaves mostly like an array but also includes an `Add` method which returns the index of the newly added item. Arrays can't change size, so such a collection could fulfill roles that an array cannot. – supercat Apr 08 '13 at 22:22
  • @supercat there is no such thing as necro, so... Your scenario seems like it could just use `ConcurrentQueue`/`Stack`, if all you want is to safely add to the end of an 'array'. You can still enumerate them without popping, and they stay in the same order. – Wolfzoon Sep 01 '21 at 14:49
  • @Wolfzoon: I don't think those types support access by index, do they? If the `Add` method of an IList-like object returned the index of the new item, then multiple threads could simultaneously and independently, without conflicts, create new entries in the list and be able to update them continuously without interference, provided that any particular item would only be updated by the thread that had added it. – supercat Sep 01 '21 at 15:11
  • @Wolfzoon: I suppose one could use a `ConcurrentDictionary` along with a static `int` that is used as a "ticket dispenser" with `Interlocked.Add` to generate keys. Probably not as efficient as a more list-like design could be, but it exists as a pre-fabricated type. – supercat Sep 01 '21 at 15:12
0

Back in 2011 I wrote a ConcurrentList<T> class (code available on GitHub), which is thread-safe, lock-free, and implements some of the IList<T> interface.

Notably, any operations that mutate the list other than Add are not supported; i.e., it is an append-only collection. So Insert, RemoveAt, etc. don't work.

Dan Tao
  • 125,917
  • 54
  • 300
  • 447
  • If `T` were constrained to `class`, could one use `CompareExchange` to change the last thing in the list from null to the new item and then use `CompareExchange` to update `_count`? If the first `CompareExchange` fails, retry the operation using the larger of `_count` and (one plus the previous `_count`). If the second fails, retry if `_count` is less than the new value. – supercat Apr 08 '13 at 22:31