1

I would like to get the same behavior as of List.Insert(Index, content ) In List , it just pushes the rest of elements forward while enables you to insert new element at specified index.

But I am dealing Concurrency so I can't use List anymore instead I need to use Concurrent collection. Any idea how we can achieve this?

Note :

I am trying to achieve custom Sorting of custom Objects stored in the concurrent collection( i.e. If at index = 2, Last Name is alphabetically less than the incoming LastName, it must allow the incoming to be placed at index = 2 , while pushing /sliding the old value to next indexes. Thus retaining all contents with new one)

Usman
  • 2,742
  • 4
  • 44
  • 82

1 Answers1

0

The ConcurrentBag<T> does not provide the functionality that you are looking for. It's not a list, it's a bag. You can't control the order of its contents, and you can't even remove a specific item from this collection. All that you can do is to Add or Take an item.

The rich functionality that you are looking for is not offered by any concurrent collection. Your best bet is probably to use a normal List<T> protected with a lock. Just make sure that you never touch the List<T> outside of a protected region. Whether you need to Add, or Insert, or Remove, or enumerate, or read an item, or read the Count, or anything else, you must always do it inside a lock region that is locked with the same object.


As a side note, it is quite likely that what you are trying to do is fundamentally wrong. There is a reason that the functionality you are asking for is not available: It's practically impossible to use it in a meaningful way without introducing race-conditions. For example two threads could independently figure out that they must insert a new item in the index 5, based on the existing values in the list, and then both try to inserting it at this index, concurrently. Both will succeed, but one of the two items will end-up in the index 6 after being pushed by the other item, and the two items might not be in the correct order in respect to each other.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
  • Thanks for your valueable comment. But I am using Thread await statements within my Insertion process as it also deals with I/O operations. Now it says await can't be used within the lock statement – Usman Apr 24 '22 at 20:35
  • Use `Semaphore` or `SemaphoreSlim` to WaitAsync (lock) and Release (unlock) asynchronously. – Thomas Angeland Apr 24 '22 at 20:41
  • @Usman yes, the `await` is not allowed inside a `lock` region, for good reasons. What you need to protect is the operations on the `List`, and nothing else. If you do anything unrelated with the `List` while holding the `lock`, you risk blocking needlessly other threads that might also want to take the lock and do something with the `List`. This is known as "contention", and might slow down your program. – Theodor Zoulias Apr 24 '22 at 20:43
  • @Usman if you are unfamiliar with the `lock` statement, you could consider using a custom thread-safe `List`, like the one that is posted as an answer in this question: [How to Create a Thread-Safe Generic List?](https://stackoverflow.com/questions/9995266/how-to-create-a-thread-safe-generic-list) – Theodor Zoulias Apr 24 '22 at 20:50
  • @TheodorZoulias : Yes, but if we introduce locks and then still would race condition occure? If locks are implemented on all those access points where collection is being accessed or modified, why Insertion can be corrupted in that case? Lock won't allow multiple threads to access collections concurrently. – Usman Apr 25 '22 at 08:46
  • @Usman if you use a `List` with a `lock`, then you can enclose in the protected region all the logic required in order to update the list. So everything will be OK, no race conditions. But if you used instead a hypothetical `ConcurrentList`, then relying on its internal synchronization wouldn't be enough to prevent race conditions. Because the operations on the `ConcurrentList`, although thread-safe, wouldn't be atomic in regard to the greater logic that you would be trying to implement. That's why such a collection doesn't exist in the standard .NET libraries. – Theodor Zoulias Apr 25 '22 at 08:58
  • 1
    @TheodorZoulias : Very thanks for your valuable comments and suggetions. I followed exactly the same ( i.e) didn't use ConcurrentCollections instead relied on locks ) – Usman Apr 25 '22 at 09:45