Был ли опыт работы с потокобезопасными коллекциями в C#?
Что проверяют
Работали ли вы с многопоточностью руками или знаете ConcurrentDictionary только по названию. Сильный ответ показывает, что потокобезопасная коллекция защищает отдельную операцию, но не вашу логику из нескольких операций. Следом обычно спрашивают про GetOrAdd или просят сравнить BlockingCollection с Channel.
Как отвечать
Начните с конкретного случая из своей практики: что за сервис, какие потоки писали и читали, почему не хватило обычного Dictionary с lock. Потом покажите, что выбирали осознанно:
ConcurrentDictionary<TKey, TValue>: кеш или реестр, куда пишут многие потоки. Чтение без блокировок, запись с блокировкой по сегментам;ConcurrentQueue<T>иConcurrentStack<T>: очередь и стек без блокировок;ConcurrentBag<T>: неупорядоченный набор, выгоден, когда один и тот же поток кладёт и забирает, например пул объектов. Как общий потокобезопасный список он не нужен;BlockingCollection<T>: производитель и потребитель с ограничением размера, но блокирует потоки;System.Threading.Channels: замена для асинхронного кода,Channel.CreateBoundedиawaitвместо блокировок;ImmutableDictionaryиFrozenDictionary: для данных, которые почти только читают.
Назовите подвохи. Фабрика в GetOrAdd и делегаты в AddOrUpdate при гонке могут выполниться несколько раз, поэтому дорогую инициализацию заворачивают в Lazy<T>. Пара ContainsKey и TryAdd не атомарна. Count захватывает все блокировки и в горячем цикле обходится дорого.
Цифры приводите свои, из замеров. Если в продакшене таких коллекций не было, скажите прямо и опишите, где применили бы и как проверили: нагрузочный тест, BenchmarkDotNet для сравнения с lock.
Где спотыкаются
Думают, что объекты внутри коллекции тоже стали потокобезопасными. Если значение словаря это изменяемый список, его защищают отдельно.
Утверждают, что конкурентные коллекции «ускоряют приложение». В одном потоке они медленнее обычных, выигрыш бывает только против грубого lock при реальной конкуренции.
Берут BlockingCollection в асинхронный код и блокируют потоки пула, хотя для этого есть Channel.