Причина, чому немає ConcurrentList, полягає в тому, що він принципово не може бути записаний. Причина полягає в тому, що кілька важливих операцій в IList покладаються на індекси, і це просто не працює. Наприклад:
int catIndex = list.IndexOf("cat");
list.Insert(catIndex, "dog");
Ефект, до якого йде автор, - це вставити "собаку" перед "кішкою", але в багатопотоковому середовищі зі списком між цими двома рядками коду може статися все, що завгодно. Наприклад, може зробити інший потік list.RemoveAt(0)
, перемістивши весь список вліво, але в принципі , catIndex не зміниться. Вплив тут полягає в тому, що Insert
операція насправді поставить «собаку» за котом, а не перед цим.
Кілька реалізацій, які ви бачите як запропоновані як "відповіді" на це запитання, є цілеспрямованими, але, як показано вище, вони не дають надійних результатів. Якщо ви дійсно хочете, щоб семантика, схожа на список, у багатопотоковому середовищі, ви не можете потрапити туди, поставивши блоки всередині методів реалізації списку. Ви повинні переконатися, що будь-який індекс, який ви використовуєте, живе цілком всередині контексту блокування. Підсумок полягає в тому, що ви можете використовувати Список у багатопотоковому середовищі з правильним блокуванням, але сам список не може бути таким, щоб існувати у цьому світі.
Якщо ви думаєте, що вам потрібен паралельний список, є дійсно дві можливості:
- Те, що вам справді потрібно - це ConcurrentBag
- Вам потрібно створити власну колекцію, можливо, реалізовану зі списком та власним контролем одночасності.
Якщо у вас є ConcurrentBag і ви перебуваєте в положенні, коли вам потрібно передати його як IList, у вас виникає проблема, оскільки метод, який ви викликаєте, вказав, що вони можуть спробувати зробити щось подібне до мене з котом & собака. У більшості світів це означає, що метод, який ви викликаєте, просто не побудований для роботи в багатопотоковому середовищі. Це означає, що ви або рефакторируйте його таким чином, щоб він був, або, якщо ви не можете, вам доведеться поводитися з цим дуже обережно. Від вас майже напевно буде потрібно створити власну колекцію із власними замками та зателефонувати до способу, що порушує її.