принятый ответ на вопрос "Почему этот код Parallel.ForEach блокирует программу?" рекомендует заменить использование списка ConcurrentBag в приложении WPF.
Я хотел бы понять, можно ли вместо этого использовать BlockingCollection?
принятый ответ на вопрос "Почему этот код Parallel.ForEach блокирует программу?" рекомендует заменить использование списка ConcurrentBag в приложении WPF.
Я хотел бы понять, можно ли вместо этого использовать BlockingCollection?
Вы действительно можете использовать BlockingCollection
, но нет абсолютно никакого смысла в этом.
Прежде всего, обратите внимание, что BlockingCollection
является оберткой вокруг коллекции, которая реализует IProducerConsumerCollection<T>
. Любой тип, реализующий этот интерфейс, может использоваться в качестве основного хранилища:
Когда вы создаете объект
BlockingCollection<T>
, вы можете указать не только ограниченная емкость, но также и тип используемой коллекции. Для Например, вы можете указать объектConcurrentQueue<T>
для первого входа, (FIFO) или объектConcurrentStack<T>
для последнего in, first out (LIFO). Вы можете использовать любой класс коллекции, который реализует интерфейсIProducerConsumerCollection<T>
. По умолчанию тип коллекции дляBlockingCollection<T>
-ConcurrentQueue<T>
.
Это включает ConcurrentBag<T>
, что означает, что вы можете иметь блокирующий параллельный пакет. Итак, какая разница между простой IProducerConsumerCollection<T>
и блокирующей коллекцией? В документации BlockingCollection
говорится (внимание мое):
BlockingCollection<T>
используется как обертка дляIProducerConsumerCollection<T>
экземпляр , позволяющий удалять попытки от коллекции до блока, пока данные не будут удалены. Аналогично, aBlockingCollection<T>
может быть создан для принудительно верхняя граница количества допустимых элементов данных вIProducerConsumerCollection<T>
[...]
Так как в связанном вопросе нет необходимости делать любую из этих вещей, использование BlockingCollection
просто добавляет слой функциональности, который не используется.
List<T>
- это коллекция, предназначенная для использования в одном потоке
приложения.
ConcurrentBag<T>
является подтипом ConcurrentCollection<T>
, разработанным
для упрощения использования коллекций в многопоточных средах. если ты
используйте ConcurrentCollection, вам не придется блокировать
для предотвращения коррупции другими потоками. Вы можете вставить
или брать данные из вашей коллекции, не требуя писать специальные коды блокировки.
BlockingCollection<T>
призван избавиться от требования
проверка наличия новых данных в общей коллекции между
потоки. если в общую коллекцию добавлены новые данные, кроме
потребительская нить пробудет незамедлительно. Поэтому вам не нужно проверять
если новые данные доступны для потребительского потока в определенное время
интервалы обычно в цикле while.Да, вы можете использовать BlockingCollection
для этого. finishedProxies
будет определяться как:
BlockingCollection<string> finishedProxies = new BlockingCollection<string>();
и добавить элемент, вы должны написать:
finishedProxies.Add(checkResult);
И когда это будет сделано, вы можете создать список из содержимого.