Методика быстрой и лучшей очереди производителя / потребителя BlockingCollection против параллельной очереди

Я использую Generic.Queue в C # 3.0 и Monitor.Enter, wait, exit for wait перед использованием очереди (подождите, пока элемент будет поставлен в очередь). Теперь я перехожу на C # 4.

Может ли кто-нибудь подсказать мне, какой из них быстрый и лучший, особенно во избежание блокировок ..

BlockingCollection против concurrentQueue или что-то еще ...

Примечание. Я не хочу ограничивать своего продюсера

Заранее спасибо..


person C-va    schedule 15.02.2011    source источник


Ответы (1)


BlockingCollection и _ 2_ существуют именно по этой причине. Сомневаюсь, что вы найдете что-нибудь лучше или проще в использовании. Команда параллельных расширений знает свое дело :)

Просто бегло проверьте версии - вы определенно используете .NET 4, а не только C # 4? (Например, вы можете использовать Visual Studio 2010 и, следовательно, C # 4, но по-прежнему ориентируетесь на .NET 3.5, и в этом случае вы не можете использовать параллельные расширения.)

Вы также можете начать изучение асинхронного шаблона на основе задач, TPL Dataflow и функции async / await C # 5 ... очевидно, что вы пока не можете их использовать, но знать, что будет дальше, не повредит.

person Jon Skeet    schedule 15.02.2011
comment
BlockingCollection и ConcurrentQueue, какой из них самый быстрый и лучший - person C-va; 15.02.2011
comment
@MSK: вы создаете ConcurrentQueue, а затем оборачиваете его в BlockingCollection, который координирует методы Add / Take. (Затем вы позволяете ему полностью управлять очередью - после этого вам не следует прикасаться непосредственно к ConcurrentQueue.) - person Jon Skeet; 15.02.2011
comment
Спасибо. Пожалуйста, предложите мне BlockingCollection / ConcurrentQueue, какой из них самый быстрый и лучший - person C-va; 15.02.2011
comment
@MSK: Вы действительно читали мой комментарий? Вы используете два типа вместе. Создайте ConcurrentQueue, а затем создайте BlockingCollection, чтобы обернуть его. Тогда используйте исключительно BlockingCollection. (Фактически, если вы просто создаете BlockingCollection, ничего не передавая конструктору, он создаст для вас ConcurrentQueue, но вы должны понимать, что происходит.) - person Jon Skeet; 15.02.2011
comment
@MSK: Я правда не знаю, что еще тебе сказать ... Я уже дважды говорил тебе, как это сделать. Вы читали документацию по BlockingCollection и приведенный там пример? - person Jon Skeet; 16.02.2011
comment
@jon: BlockingCollection ‹int› bc = new BlockingCollection ‹int› (); Задача t1 = Task.Factory.StartNew (() = ›{bc.Add (1); bc.Add (2); bc.Add (3); bc.CompleteAdding ();}); Задача t2 = Task.Factory.StartNew (() = ›{попробуйте {while (true) Console.WriteLine (bc.Take ());}}}); - person C-va; 16.02.2011
comment
@ jon: В приведенном выше коде Will the Take () ожидает, если очередь пуста, и возобновляет автоматическое удаление из очереди при добавлении нового элемента (без использования ожидания / сигнала). Или я не использую monitor.wai, pulseall / ManualResetEvent? - person C-va; 16.02.2011
comment
@MSK: Что говорится в документации по BlockingCollection.Take? (Вы также можете посмотреть BlockingCollection.GetConsumingEnumerable ()). - person Jon Skeet; 16.02.2011
comment
@jon: берет предмет из коллекции BlockingCollection ‹T›. Вызов Take может заблокировать, пока элемент не станет доступным для удаления. - person C-va; 16.02.2011
comment
@MSK: Совершенно верно. Поэтому, если очередь пуста, она будет заблокирована до тех пор, пока в ней не появится элемент. Весь смысл использования типа заключается в том, чтобы избежать использования Wait и т. Д. - person Jon Skeet; 16.02.2011
comment
@jon: Я немного не понимал, возобновится он или нет. Вот почему повторение в моем вопросе. К. Теперь им ясно. Большое спасибо. - person C-va; 16.02.2011
comment
Один момент по поводу ConcurrentQueue, с которым я только что столкнулся с реализацией Pro / Con ... blogs.msdn.com/b/pfxteam/archive/2012/05/08/ Ничего страшного, если предметы маленькие ... серьезная проблема, если они большие (как у меня) - person Dave Lawrence; 11.10.2012
comment
Я бы поставил +10 этому посту, если бы мог, я действительно серьезно! Кстати, BlockingCollection можно повторить с помощью Parallel.For, который похож по полезности на PCQ и, возможно, немного проще (может быть, НАМНОГО проще) для создания кода. - person code4life; 08.05.2013
comment
BlockingCollection по умолчанию обертывает ConcurrentQueue - msdn.microsoft.com /en-us/library/dd267312(v=vs.110).aspx - person jjxtra; 02.07.2014