IProducerConsumerCollection‹T›.TryAdd/.TryTake — когда они возвращают true/false?

Когда я вызову IProducerConsumerCollection<T>.TryAdd(<T>) или IProducerConsumerCollection<T>.TryTake(out <T>), они когда-нибудь потерпят неудачу, потому что другой поток использует коллекцию?

Или дело в том, что если есть место для добавления или что-то взять, даже после того, как другой поток завершил сбор, он всегда будет возвращать значение true?

Ничего, что я вижу здесь: http://msdn.microsoft.com/en-us/library/dd287147.aspx


person Cheetah    schedule 10.01.2013    source источник


Ответы (2)


Хотя теоретически коллекции могут отклонять запросы на добавление/принятие по любой причине, единственная причина, о которой я известен, заключается в том, что Add сбой из-за того, что коллекция достиг своего предела, и Take сбой из-за того, что коллекция пуста.

Коллекции с самого начала разрабатываются для использования несколькими потоками, поэтому, если остались элементы, даже если два потока пытаются выполнить Take одновременно, они оба должны получить элемент и возвращаемое значение true.

person Jon Skeet    schedule 10.01.2013
comment
Чтобы немного расширить вышеизложенное: наиболее известным сценарием, использующим IProducerConsumerCollection<T>, является BlockingCollection<T>, и он использует тайм-ауты только с целью ожидания, пока в коллекции будет место (для TryAdd()) или будет элемент (для TryTake()). Конкуренция обрабатывается независимо от тайм-аута, указанного пользователем. См., например. referencesource.microsoft.com/#System/sys/ система/коллекции/ - person Peter Duniho; 03.07.2016
comment
Поскольку BlockingCollection<T> не реализует интерфейс, это не совсем точно, но показывает, как Microsoft ожидает реализации этих методов. Сам интерфейс не поддерживает тайм-ауты (поэтому тайм-ауты, очевидно, не будут иметь отношения к успеху/неуспеху), и даже в неинтерфейсных реализациях в BlockingCollection<T> тайм-ауты относятся только к полному/пустому состоянию коллекции, как и в не-интерфейсных реализациях. сценарий тайм-аута, и ничего больше. - person Peter Duniho; 03.07.2016

Например, BlockingCollection<T>, который представляет собой высокоуровневую абстракцию над интерфейсом (хотя и не реализует интерфейс) с возможностями ограничения и блокировки, может вызвать одно из следующих :

  • ObjectDisposedException в TryAdd(T) или TryTake(T)< /strong> после удаления коллекции.
  • InvalidOperationException для TryAdd(T), если он помечен как завершенный для добавления. Подумайте о ситуации, когда вы добавляете значения в коллекцию от двух производителей, один помечает коллекцию как завершенную, а затем другой пытается добавить в коллекцию.
person Andrey Taptunov    schedule 10.01.2013