IProducerConsumerCollection<T> 接口
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
定义用于操作用于生成者/使用者使用的线程安全集合的方法。 此接口为生成者/使用者集合提供统一表示形式,以便更高级别的抽象(如 BlockingCollection<T>)可以使用集合作为基础存储机制。
generic <typename T>
public interface class IProducerConsumerCollection : System::Collections::Generic::IEnumerable<T>, System::Collections::ICollection
public interface IProducerConsumerCollection<T> : System.Collections.Generic.IEnumerable<T>, System.Collections.ICollection
type IProducerConsumerCollection<'T> = interface
interface seq<'T>
interface IEnumerable
interface ICollection
type IProducerConsumerCollection<'T> = interface
interface seq<'T>
interface ICollection
interface IEnumerable
Public Interface IProducerConsumerCollection(Of T)
Implements ICollection, IEnumerable(Of T)
类型参数
- T
指定集合中的元素类型。
- 派生
- 实现
示例
以下示例演示实现 System.Collections.Concurrent.IProducerConsumerCollection<T>的堆栈数据结构。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
// Sample implementation of IProducerConsumerCollection(T)
// -- in this case, a thread-safe stack.
public class SafeStack<T> : IProducerConsumerCollection<T>
{
// Used for enforcing thread-safety
private object m_lockObject = new object();
// We'll use a regular old Stack for our core operations
private Stack<T> m_sequentialStack = null;
//
// Constructors
//
public SafeStack()
{
m_sequentialStack = new Stack<T>();
}
public SafeStack(IEnumerable<T> collection)
{
m_sequentialStack = new Stack<T>(collection);
}
//
// Safe Push/Pop support
//
public void Push(T item)
{
lock (m_lockObject) m_sequentialStack.Push(item);
}
public bool TryPop(out T item)
{
bool rval = true;
lock (m_lockObject)
{
if (m_sequentialStack.Count == 0) { item = default(T); rval = false; }
else
{
item = m_sequentialStack.Pop();
}
}
return rval;
}
//
// IProducerConsumerCollection(T) support
//
public bool TryTake(out T item)
{
return TryPop(out item);
}
public bool TryAdd(T item)
{
Push(item);
return true; // Push doesn't fail
}
public T[] ToArray()
{
T[] rval = null;
lock (m_lockObject) rval = m_sequentialStack.ToArray();
return rval;
}
public void CopyTo(T[] array, int index)
{
lock (m_lockObject) m_sequentialStack.CopyTo(array, index);
}
//
// Support for IEnumerable(T)
//
public IEnumerator<T> GetEnumerator()
{
// The performance here will be unfortunate for large stacks,
// but thread-safety is effectively implemented.
Stack<T> stackCopy = null;
lock (m_lockObject) stackCopy = new Stack<T>(m_sequentialStack);
return stackCopy.GetEnumerator();
}
//
// Support for IEnumerable
//
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<T>)this).GetEnumerator();
}
//
// Support for ICollection
//
public bool IsSynchronized
{
get { return true; }
}
public object SyncRoot
{
get { return m_lockObject; }
}
public int Count
{
get { return m_sequentialStack.Count; }
}
public void CopyTo(Array array, int index)
{
lock (m_lockObject) ((ICollection)m_sequentialStack).CopyTo(array, index);
}
}
public class Program
{
static void Main()
{
TestSafeStack();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
// Test our implementation of IProducerConsumerCollection(T)
// Demonstrates:
// IPCC(T).TryAdd()
// IPCC(T).TryTake()
// IPCC(T).CopyTo()
static void TestSafeStack()
{
SafeStack<int> stack = new SafeStack<int>();
IProducerConsumerCollection<int> ipcc = (IProducerConsumerCollection<int>)stack;
// Test Push()/TryAdd()
stack.Push(10); Console.WriteLine("Pushed 10");
ipcc.TryAdd(20); Console.WriteLine("IPCC.TryAdded 20");
stack.Push(15); Console.WriteLine("Pushed 15");
int[] testArray = new int[3];
// Try CopyTo() within boundaries
try
{
ipcc.CopyTo(testArray, 0);
Console.WriteLine("CopyTo() within boundaries worked, as expected");
}
catch (Exception e)
{
Console.WriteLine("CopyTo() within boundaries unexpectedly threw an exception: {0}", e.Message);
}
// Try CopyTo() that overflows
try
{
ipcc.CopyTo(testArray, 1);
Console.WriteLine("CopyTo() with index overflow worked, and it SHOULD NOT HAVE");
}
catch (Exception e)
{
Console.WriteLine("CopyTo() with index overflow threw an exception, as expected: {0}", e.Message);
}
// Test enumeration
Console.Write("Enumeration (should be three items): ");
foreach (int item in stack) Console.Write("{0} ", item);
Console.WriteLine("");
// Test TryPop()
int popped = 0;
if (stack.TryPop(out popped))
{
Console.WriteLine("Successfully popped {0}", popped);
}
else
{
Console.WriteLine("FAILED to pop!!");
}
// Test Count
Console.WriteLine("stack count is {0}, should be 2", stack.Count);
// Test TryTake()
if (ipcc.TryTake(out popped))
{
Console.WriteLine("Successfully IPCC-TryTaked {0}", popped);
}
else
{
Console.WriteLine("FAILED to IPCC.TryTake!!");
}
}
}
Imports System.Collections.Concurrent
Module IProdCon
' Sample implementation of IProducerConsumerCollection(T) -- in this case,
' a thread-safe stack.
Public Class SafeStack(Of T)
Implements IProducerConsumerCollection(Of T)
' Used for enforcing thread-safety
Private m_lockObject As New Object()
' We'll use a regular old Stack for our core operations
Private m_sequentialStack As Stack(Of T) = Nothing
'
' Constructors
'
Public Sub New()
m_sequentialStack = New Stack(Of T)()
End Sub
Public Sub New(ByVal collection As IEnumerable(Of T))
m_sequentialStack = New Stack(Of T)(collection)
End Sub
'
' Safe Push/Pop support
'
Public Sub Push(ByVal item As T)
SyncLock m_lockObject
m_sequentialStack.Push(item)
End SyncLock
End Sub
Public Function TryPop(ByRef item As T) As Boolean
Dim rval As Boolean = True
SyncLock m_lockObject
If m_sequentialStack.Count = 0 Then
item = Nothing
rval = False
Else
item = m_sequentialStack.Pop()
End If
End SyncLock
Return rval
End Function
'
' IProducerConsumerCollection(T) support
'
Public Function TryTake(ByRef item As T) As Boolean Implements IProducerConsumerCollection(Of T).TryTake
Return TryPop(item)
End Function
Public Function TryAdd(ByVal item As T) As Boolean Implements IProducerConsumerCollection(Of T).TryAdd
Push(item)
' Push doesn't fail
Return True
End Function
Public Function ToArray() As T() Implements IProducerConsumerCollection(Of T).ToArray
Dim rval As T() = Nothing
SyncLock m_lockObject
rval = m_sequentialStack.ToArray()
End SyncLock
Return rval
End Function
Public Sub CopyTo(ByVal array As T(), ByVal index As Integer) Implements IProducerConsumerCollection(Of T).CopyTo
SyncLock m_lockObject
m_sequentialStack.CopyTo(array, index)
End SyncLock
End Sub
'
' Support for IEnumerable(T)
'
Public Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
' The performance here will be unfortunate for large stacks,
' but thread-safety is effectively implemented.
Dim stackCopy As Stack(Of T) = Nothing
SyncLock m_lockObject
stackCopy = New Stack(Of T)(m_sequentialStack)
End SyncLock
Return stackCopy.GetEnumerator()
End Function
'
' Support for IEnumerable
'
Private Function GetEnumerator2() As IEnumerator Implements IEnumerable.GetEnumerator
Return DirectCast(Me, IEnumerable(Of T)).GetEnumerator()
End Function
'
' Support for ICollection
'
Public ReadOnly Property IsSynchronized() As Boolean Implements ICollection.IsSynchronized
Get
Return True
End Get
End Property
Public ReadOnly Property SyncRoot() As Object Implements ICollection.SyncRoot
Get
Return m_lockObject
End Get
End Property
Public ReadOnly Property Count() As Integer Implements ICollection.Count
Get
Return m_sequentialStack.Count
End Get
End Property
Public Sub CopyTo(ByVal array As Array, ByVal index As Integer) Implements ICollection.CopyTo
SyncLock m_lockObject
DirectCast(m_sequentialStack, ICollection).CopyTo(array, index)
End SyncLock
End Sub
End Class
' Test our implementation of IProducerConsumerCollection(T)
' Demonstrates:
' IPCC(T).TryAdd()
' IPCC(T).TryTake()
' IPCC(T).CopyTo()
Private Sub TestSafeStack()
Dim stack As New SafeStack(Of Integer)()
Dim ipcc As IProducerConsumerCollection(Of Integer) = DirectCast(stack, IProducerConsumerCollection(Of Integer))
' Test Push()/TryAdd()
stack.Push(10)
Console.WriteLine("Pushed 10")
ipcc.TryAdd(20)
Console.WriteLine("IPCC.TryAdded 20")
stack.Push(15)
Console.WriteLine("Pushed 15")
Dim testArray As Integer() = New Integer(2) {}
' Try CopyTo() within boundaries
Try
ipcc.CopyTo(testArray, 0)
Console.WriteLine("CopyTo() within boundaries worked, as expected")
Catch e As Exception
Console.WriteLine("CopyTo() within boundaries unexpectedly threw an exception: {0}", e.Message)
End Try
' Try CopyTo() that overflows
Try
ipcc.CopyTo(testArray, 1)
Console.WriteLine("CopyTo() with index overflow worked, and it SHOULD NOT HAVE")
Catch e As Exception
Console.WriteLine("CopyTo() with index overflow threw an exception, as expected: {0}", e.Message)
End Try
' Test enumeration
Console.Write("Enumeration (should be three items): ")
For Each item As Integer In stack
Console.Write("{0} ", item)
Next
Console.WriteLine("")
' Test TryPop()
Dim popped As Integer = 0
If stack.TryPop(popped) Then
Console.WriteLine("Successfully popped {0}", popped)
Else
Console.WriteLine("FAILED to pop!!")
End If
' Test Count
Console.WriteLine("stack count is {0}, should be 2", stack.Count)
' Test TryTake()
If ipcc.TryTake(popped) Then
Console.WriteLine("Successfully IPCC-TryTaked {0}", popped)
Else
Console.WriteLine("FAILED to IPCC.TryTake!!")
End If
End Sub
Sub Main()
TestSafeStack()
' Keep the console window open in debug mode
Console.WriteLine("Press any key to exit.")
Console.ReadKey()
End Sub
End Module
注解
有关详细信息,请参阅 Thread-Safe 集合 和 BlockingCollection 概述。
属性
Count |
获取 ICollection中包含的元素数。 (继承自 ICollection) |
IsSynchronized |
获取一个值,该值指示是否同步对 ICollection 的访问(线程安全)。 (继承自 ICollection) |
SyncRoot |
获取可用于同步对 ICollection的访问的对象。 (继承自 ICollection) |
方法
CopyTo(Array, Int32) |
从特定 Array 索引开始,将 ICollection 的元素复制到 Array。 (继承自 ICollection) |
CopyTo(T[], Int32) |
从指定的索引处开始,将 IProducerConsumerCollection<T> 的元素复制到 Array。 |
GetEnumerator() |
返回循环访问集合的枚举器。 (继承自 IEnumerable) |
ToArray() |
将 IProducerConsumerCollection<T> 中包含的元素复制到新数组。 |
TryAdd(T) |
尝试将对象添加到 IProducerConsumerCollection<T>。 |
TryTake(T) |
尝试从 IProducerConsumerCollection<T>中删除和返回对象。 |
扩展方法
适用于
线程安全性
此接口的所有实现都必须使此接口的所有成员能够从多个线程并发使用。