ConcurrentBag\<T> является частью пространства имен System.Collections.Concurrent в .NET Framework, предоставляющим потокобезопасные коллекции для параллельного программирования.
ConcurrentBag позволяет нескольким потокам одновременно добавлять и извлекать элементы без необходимости во внешней синхронизации.
<br>
Основные характеристики ConcurrentBag\<T>:
* **Неблокирующая коллекция**: Потоки могут одновременно добавлять и извлекать элементы из ConcurrentBag\<T>. Это означает, что один поток может безопасно добавлять элементы, пока другой поток извлекает элементы, и наоборот.
* **Неупорядоченность**: ConcurrentBag\<T> не гарантирует никакого конкретного порядка элементов. Если порядок добавления или извлечения важен, вам, вероятно, следует использовать другую коллекцию, такую как ConcurrentQueue\<T> или ConcurrentStack\<T>.
* **Размер неизвестен**: Поскольку элементы могут одновременно добавляться и удаляться из разных потоков, количество элементов в ConcurrentBag\<T> может изменяться мгновенно.
<br>
Следующий пример кода иллюстрирует, как можно использовать ConcurrentBag\<T>:
```csharp
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
ConcurrentBag<int> bag = new ConcurrentBag<int>();
Task[] tasks = new Task[10];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = Task.Factory.StartNew((param) =>
{
var item = (int)param;
bag.Add(item);
int result;
if (bag.TryPeek(out result))
{
Console.WriteLine("Task {0} has peeked at an item of {1}", Task.CurrentId, result);
}
}, i);
}
Task.WaitAll(tasks);
int itemOut;
while (bag.TryTake(out itemOut))
{
Console.WriteLine("Removed {0}", itemOut);
}
}
}
```
В этом примере создается ConcurrentBag\<int>, и 10 потоков добавляют элементы в коллекцию. Каждый поток добавляет элемент, а затем пытается "заглянуть" в коллекцию, чтобы увидеть последний добавленный элемент. Затем главный поток удаляет все элементы из коллекции.