Does BlockingCollection <T> гарантирует порядок удаления?
У меня есть ограниченная блокирующая очередь в приложении, которое было написано несколько лет назад. Скажем, что реализация менее звездная, но она сработала. Однако у него есть некоторые проблемы с производительностью. Похоже, что .NET 4.0 BlockingCollection<T>
- это правильная замена, но мне нужно убедиться, что это фактически очередь. То есть, гарантируется ли это строго FIFO, если он используется в однопрофильной форме с одним потребителем?
В документации конкретно не говорится. Тема BlockingCollection говорит (в примечаниях):
BlockingCollection<T>
аналогичен данные традиционной блокировки структуры, за исключением того, что механизм хранения данных абстрагирован как IProducerConsumerCollection<T>
.
Но ничего конкретно не говорится о том, что вещи будут удалены в том же порядке, в котором они добавлены.
Кто-нибудь знает наверняка?
Ответы
Ответ 1
Ну, BlockingCollection<T>
действительно предназначен для параллельной работы, где у вас есть несколько одновременных "производителей" и один потребитель (используя GetConsumingEnumerable()).
В этой ситуации у вас нет способа гарантировать порядок вставки, поэтому ограничения порядка не указаны.
При этом BlockingCollection<T>
работает с любым IProducerConsumerCollection<T>
(указанным в конструкторе). Если вы не укажете его в конструкторе, он будет использовать ConcurrentQueue<T>
. Это приводит к тому, что он является FIFO, поскольку он будет фактически (внутри) очереди. Так что да, по умолчанию он будет "гарантированно строго FIFO, если он используется в однопроцессорном, однопользовательском режиме", по крайней мере, в текущей реализации. Если вы хотите принудительно выполнить это для будущей проверки (поскольку очередь представляет собой деталь реализации), просто создайте ее как:
var blockingCollection = new BlockingCollection<MyClass>(new ConcurrentQueue<MyClass>());
Это гарантирует, что он использует очередь сейчас и в будущем (поскольку очередь представляет собой деталь реализации).
Ответ 2
Возможно, документация MSDN была обновлена с момента этого вопроса, но теперь ясно сказано, что BlockingCollection будет по умолчанию использовать FIFO, если не указано иное.
см:
https://msdn.microsoft.com/en-us/library/dd997371(v=vs.110).aspx
или в случае, если MS изменит ссылку google 'MSDN BlockingCollection Overview'
NET Framework 4.6 и 4.5
Ищите "Указание типа коллекции" на этой странице.