TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.77K subscribers
Post #299 606
День двести пятьдесят девятый. #ЗаметкиНаПолях
Использование потокобезопасных коллекций. Окончание
BlockingCollection<Т>
С точки зрения разработки лучше всего реализовывать паттерн «производитель/потребитель», то есть рассматривать задачи в многопоточном приложении как либо производителя, либо потребителя данных. Задача, которая и производит, и потребляет данные, уязвима для ситуаций «взаимной блокировки». Если задача A ожидает чего-то, создаваемого задачей B, а задача B ожидает чего-то, создаваемого задачей A, и ни одна из задач не может быть запущена.
Класс BlockingCollection<T> обеспечивает потокобезопасное средство добавления и извлечения элементов из хранилища данных. Он называется блокирующей коллекцией, потому что действие Take блокирует задачу, если нет элементов, которые необходимо извлечь. Попытки добавить элементы в заполненную коллекцию также блокируются. Кроме того, можно установить верхний предел размера коллекции.
Следующий код создаёт поток, который пытается добавить 5 элементов в коллекцию BlockingCollection из 3 элементов. После добавления 3-го элемента этот поток блокируется. Программа также создаёт поток, который извлекает элементы из коллекции. Как только поток чтения начинает работать и извлекает некоторые элементы из коллекции, поток записи может продолжиться:
BlockingCollection<int> data = new BlockingCollection<int>(3);
Task.Run(() =>
{
for(int i=1;i<=5;i++)
{
data.Add(i);
Console.WriteLine("Число {0} добавлено.", i);
}
data.CompleteAdding();
});
Console.ReadKey();
Console.WriteLine("Чтение элементов");
Task.Run(() =>
{
while (!data.IsCompleted)
{
try
{
int v = data.Take();
Console.WriteLine("Число {0} прочитано.", v);
}
catch (InvalidOperationException) { }
}
});
Console.ReadKey();


Пример вывода:
Число 1 добавлено
Число 2 добавлено
Число 3 добавлено
Чтение элементов
Число 1 прочитано
Число 2 прочитано
Число 3 прочитано
Число 4 добавлено
Число 5 добавлено
Число 4 прочитано
Число 5 прочитано

Задача добавления вызывает метод CompleteAdding(), после добавления последнего элемента. Это предотвращает добавление новых элементов в коллекцию. Извлекающая задача использует свойство IsCompleted, чтобы определить, когда прекратить получать элементы. Свойство IsCompleted возвращает true, когда коллекция пуста и вызван CompleteAdding. Операция извлечения выполняется внутри конструкции try-catch, т.к. метод Take может выбросить исключение, если между проверкой IsCompleted и вызовом Take добавляющая задача вызовет CompleteAdding. То есть получающая задача попытается выполнить извлечение из коллекции, которая была помечена как завершённая.
BlockingCollection также предоставляет методы TryAdd и TryTake, которые используются для попытки выполнения действия. Они возвращает true, если действие выполнено успешно. Кроме того, им можно передать максимальное время ожидания завершения действия и токен отмены. Класс BlockingCollection выступает в качестве оболочки для других потокобезопасных классов коллекций, включая ConcurrentQueue (используется по умолчанию), ConcurrentStack и ConcurrentBag.

Источник: Rob Miles “Exam Ref 70-483 Programming in C#”. 2nd ed - Pearson Education, Inc., 2019. Глава 1.
More from @netdeveloperdiary
  1. Oct 12, 2026День 2812. #Карьера #AI Как Разработчикам Оставаться Полезными, Когда Код Пишет ИИ? По мер…
  2. Oct 11, 2026День 2811. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  3. Oct 10, 2026День 2810. #ЧтоНовенького #VSCode Более Быстрый и Лёгкий C# Dev Kit Мы, разработчики, люби…
  4. Oct 9, 2026День 2809. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Окончание Начало 3.…
  5. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
  6. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →