Подтвердить что ты не робот

Does BlockingCollection <T> гарантирует порядок удаления?

У меня есть ограниченная блокирующая очередь в приложении, которое было написано несколько лет назад. Скажем, что реализация менее звездная, но она сработала. Однако у него есть некоторые проблемы с производительностью. Похоже, что .NET 4.0 BlockingCollection<T> - это правильная замена, но мне нужно убедиться, что это фактически очередь. То есть, гарантируется ли это строго FIFO, если он используется в однопрофильной форме с одним потребителем?

В документации конкретно не говорится. Тема BlockingCollection говорит (в примечаниях):

BlockingCollection<T> аналогичен данные традиционной блокировки структуры, за исключением того, что механизм хранения данных абстрагирован как IProducerConsumerCollection<T>.

Но ничего конкретно не говорится о том, что вещи будут удалены в том же порядке, в котором они добавлены.

Кто-нибудь знает наверняка?

4b9b3361

Ответ 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

Ищите "Указание типа коллекции" на этой странице.