ConcurrentBag<T> 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
表示对象的线程安全无序集合。
generic <typename T>
public ref class ConcurrentBag : System::Collections::Concurrent::IProducerConsumerCollection<T>, System::Collections::Generic::IEnumerable<T>, System::Collections::Generic::IReadOnlyCollection<T>, System::Collections::ICollection
generic <typename T>
public ref class ConcurrentBag : System::Collections::Concurrent::IProducerConsumerCollection<T>, System::Collections::Generic::IEnumerable<T>
generic <typename T>
public ref class ConcurrentBag : System::Collections::Concurrent::IProducerConsumerCollection<T>, System::Collections::Generic::IEnumerable<T>, System::Collections::Generic::IReadOnlyCollection<T>
generic <typename T>
public ref class ConcurrentBag : System::Collections::Concurrent::IProducerConsumerCollection<T>, System::Collections::Generic::IEnumerable<T>, System::Collections::ICollection
public class ConcurrentBag<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.ICollection
[System.Runtime.InteropServices.ComVisible(false)]
[System.Serializable]
public class ConcurrentBag<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>
[System.Runtime.InteropServices.ComVisible(false)]
[System.Serializable]
public class ConcurrentBag<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>
public class ConcurrentBag<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.ICollection
public class ConcurrentBag<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>
type ConcurrentBag<'T> = class
interface IProducerConsumerCollection<'T>
interface seq<'T>
interface IEnumerable
interface ICollection
interface IReadOnlyCollection<'T>
[<System.Runtime.InteropServices.ComVisible(false)>]
[<System.Serializable>]
type ConcurrentBag<'T> = class
interface IProducerConsumerCollection<'T>
interface seq<'T>
interface ICollection
interface IEnumerable
[<System.Runtime.InteropServices.ComVisible(false)>]
[<System.Serializable>]
type ConcurrentBag<'T> = class
interface IProducerConsumerCollection<'T>
interface seq<'T>
interface IEnumerable
interface ICollection
interface IReadOnlyCollection<'T>
type ConcurrentBag<'T> = class
interface IProducerConsumerCollection<'T>
interface seq<'T>
interface ICollection
interface IEnumerable
Public Class ConcurrentBag(Of T)
Implements ICollection, IEnumerable(Of T), IProducerConsumerCollection(Of T), IReadOnlyCollection(Of T)
Public Class ConcurrentBag(Of T)
Implements IEnumerable(Of T), IProducerConsumerCollection(Of T)
Public Class ConcurrentBag(Of T)
Implements IEnumerable(Of T), IProducerConsumerCollection(Of T), IReadOnlyCollection(Of T)
Public Class ConcurrentBag(Of T)
Implements ICollection, IEnumerable(Of T), IProducerConsumerCollection(Of T)
类型参数
- T
要存储在集合中的元素的类型。
- 继承
-
ConcurrentBag<T>
- 属性
- 实现
示例
以下示例演示如何从
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
class ConcurrentBagDemo
{
// Demonstrates:
// ConcurrentBag<T>.Add()
// ConcurrentBag<T>.IsEmpty
// ConcurrentBag<T>.TryTake()
// ConcurrentBag<T>.TryPeek()
static void Main()
{
// Add to ConcurrentBag concurrently
ConcurrentBag<int> cb = new ConcurrentBag<int>();
List<Task> bagAddTasks = new List<Task>();
for (int i = 0; i < 500; i++)
{
var numberToAdd = i;
bagAddTasks.Add(Task.Run(() => cb.Add(numberToAdd)));
}
// Wait for all tasks to complete
Task.WaitAll(bagAddTasks.ToArray());
// Consume the items in the bag
List<Task> bagConsumeTasks = new List<Task>();
int itemsInBag = 0;
while (!cb.IsEmpty)
{
bagConsumeTasks.Add(Task.Run(() =>
{
int item;
if (cb.TryTake(out item))
{
Console.WriteLine(item);
Interlocked.Increment(ref itemsInBag);
}
}));
}
Task.WaitAll(bagConsumeTasks.ToArray());
Console.WriteLine($"There were {itemsInBag} items in the bag");
// Checks the bag for an item
// The bag should be empty and this should not print anything
int unexpectedItem;
if (cb.TryPeek(out unexpectedItem))
Console.WriteLine("Found an item in the bag when it should be empty");
}
}
module ConcurrentBagDemo
open System.Collections.Concurrent
open System.Threading.Tasks
open System.Threading
// Demonstrates:
// ConcurrentBag<T>.Add()
// ConcurrentBag<T>.IsEmpty
// ConcurrentBag<T>.TryTake()
// ConcurrentBag<T>.TryPeek()
// Add to ConcurrentBag concurrently
let cb = ConcurrentBag<int>()
let bagAddTasks =
[| for i = 0 to 499 do
let numberToAdd = i
task { cb.Add numberToAdd } :> Task |]
// Wait for all tasks to complete
Task.WaitAll bagAddTasks
// Consume the items in the bag
let mutable itemsInBag = 0
let bagConsumeTasks =
[| while not cb.IsEmpty do
task {
let mutable item = 0
if cb.TryTake &item then
printfn $"{item}"
Interlocked.Increment &itemsInBag |> ignore
}
:> Task |]
Task.WaitAll bagConsumeTasks
printfn $"There were {itemsInBag} items in the bag"
// Checks the bag for an item
// The bag should be empty and this should not print anything
let mutable unexpectedItem = 0
if cb.TryPeek &unexpectedItem then
printfn "Found an item in the bag when it should be empty"
Imports System.Collections.Concurrent
Module ConcurrentBagDemo
' Demonstrates:
' ConcurrentBag<T>.Add()
' ConcurrentBag<T>.IsEmpty
' ConcurrentBag<T>.TryTake()
' ConcurrentBag<T>.TryPeek()
Sub Main()
' Add to ConcurrentBag concurrently
Dim cb As New ConcurrentBag(Of Integer)()
Dim bagAddTasks As New List(Of Task)()
For i = 1 To 500
Dim numberToAdd As Integer = i
bagAddTasks.Add(Task.Run(Sub() cb.Add(numberToAdd)))
Next
' Wait for all tasks to complete
Task.WaitAll(bagAddTasks.ToArray())
' Consume the items in the bag
Dim bagConsumeTasks As New List(Of Task)()
Dim itemsInBag As Integer = 0
While Not cb.IsEmpty
bagConsumeTasks.Add(Task.Run(Sub()
Dim item As Integer
If cb.TryTake(item) Then
Console.WriteLine(item)
itemsInBag = itemsInBag + 1
End If
End Sub))
End While
Task.WaitAll(bagConsumeTasks.ToArray())
Console.WriteLine($"There were {itemsInBag} items in the bag")
' Checks the bag for an item
' The bag should be empty and this should not print anything
Dim unexpectedItem As Integer
If cb.TryPeek(unexpectedItem) Then
Console.WriteLine("Found an item in the bag when it should be empty")
End If
End Sub
End Module
注解
包可用于在排序无关紧要时存储对象,与集不同,包支持重复项。 ConcurrentBag<T> 是一种线程安全包实现,针对同一线程将同时生成和使用存储在包中的数据的方案进行优化。
ConcurrentBag<T> 接受 null 为引用类型的有效值。
有关详细信息,请参阅FAQ 的条目:所有新的并发集合是否都是无锁的?与 .NET 博客并行编程。
构造函数
| 名称 | 说明 |
|---|---|
| ConcurrentBag<T>() |
初始化 ConcurrentBag<T> 类的新实例。 |
| ConcurrentBag<T>(IEnumerable<T>) |
初始化包含从指定集合复制的元素的 ConcurrentBag<T> 类的新实例。 |
属性
| 名称 | 说明 |
|---|---|
| Count |
获取包含在 . 中的 ConcurrentBag<T>元素数。 |
| IsEmpty |
获取一个值,该值指示是否为 ConcurrentBag<T> 空。 |
方法
| 名称 | 说明 |
|---|---|
| Add(T) |
将对象添加到 .ConcurrentBag<T> |
| Clear() |
从 . ConcurrentBag<T>中删除所有值。 |
| CopyTo(T[], Int32) |
从指定的数组索引处开始,将 ConcurrentBag<T> 元素复制到现有的一维 Array。 |
| Equals(Object) |
确定指定的对象是否等于当前对象。 (继承自 Object) |
| GetEnumerator() |
返回循环访问的 ConcurrentBag<T>枚举数。 |
| GetHashCode() |
用作默认哈希函数。 (继承自 Object) |
| GetType() |
获取当前实例的 Type。 (继承自 Object) |
| MemberwiseClone() |
创建当前 Object的浅表副本。 (继承自 Object) |
| ToArray() |
将 ConcurrentBag<T> 元素复制到新数组。 |
| ToString() |
返回一个表示当前对象的字符串。 (继承自 Object) |
| TryPeek(T) |
尝试从中 ConcurrentBag<T> 返回对象而不将其删除。 |
| TryTake(T) |
尝试从 . ConcurrentBag<T>. 中删除和返回对象。 |
显式接口实现
| 名称 | 说明 |
|---|---|
| ICollection.CopyTo(Array, Int32) |
将元素ICollection复制到从特定Array索引开始的元素Array。 |
| ICollection.IsSynchronized |
获取一个值,该值指示访问 ICollection 是否与 SyncRoot 同步。 |
| ICollection.SyncRoot |
获取可用于同步对 . ICollection的访问的对象。 不支持此属性。 |
| IEnumerable.GetEnumerator() |
返回循环访问的 ConcurrentBag<T>枚举数。 |
| IProducerConsumerCollection<T>.TryAdd(T) |
尝试将对象添加到 .ConcurrentBag<T> |
扩展方法
适用于
线程安全性
所有公共成员和受保护的成员 ConcurrentBag<T> 都是线程安全的,并且可以同时从多个线程使用。 但是,实现(包括扩展方法)通过其中一个接口 ConcurrentBag<T> 访问的成员不能保证线程安全,并且可能需要由调用方同步。