ConcurrentStack<T> ConcurrentStack<T> ConcurrentStack<T> ConcurrentStack<T> Class

定义

表示线程安全的后进先出 (LIFO) 集合。Represents a thread-safe last in-first out (LIFO) collection.

generic <typename T>
public ref class ConcurrentStack : System::Collections::Concurrent::IProducerConsumerCollection<T>, System::Collections::Generic::IEnumerable<T>, System::Collections::Generic::IReadOnlyCollection<T>
[System.Serializable]
public class ConcurrentStack<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>
type ConcurrentStack<'T> = class
    interface IProducerConsumerCollection<'T>
    interface IReadOnlyCollection<'T>
    interface seq<'T>
    interface ICollection
    interface IEnumerable
Public Class ConcurrentStack(Of T)
Implements IEnumerable(Of T), IProducerConsumerCollection(Of T), IReadOnlyCollection(Of T)

类型参数

T

堆栈中包含的元素的类型。The type of the elements contained in the stack.

继承
ConcurrentStack<T>ConcurrentStack<T>ConcurrentStack<T>ConcurrentStack<T>
属性
实现

示例

下面的示例演示如何使用ConcurrentStack<T>来推送和弹出各个项:The following example shows how to use a ConcurrentStack<T> to push and pop individual items:

using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;

class Example
{
    // Demonstrates:
    //      ConcurrentStack<T>.Push();
    //      ConcurrentStack<T>.TryPeek();
    //      ConcurrentStack<T>.TryPop();
    //      ConcurrentStack<T>.Clear();
    //      ConcurrentStack<T>.IsEmpty;
    static async Task Main()
    {
        int items = 10000;

        ConcurrentStack<int> stack = new ConcurrentStack<int>();

        // Create an action to push items onto the stack
        Action pusher = () =>
        {
            for (int i = 0; i < items; i++)
            {
                stack.Push(i);
            }
        };

        // Run the action once
        pusher();

        if (stack.TryPeek(out int result))
        {
            Console.WriteLine($"TryPeek() saw {result} on top of the stack.");
        }
        else
        {
            Console.WriteLine("Could not peek most recently added number.");
        }

        // Empty the stack
        stack.Clear();

        if (stack.IsEmpty)
        {
            Console.WriteLine("Cleared the stack.");
        }

        // Create an action to push and pop items
        Action pushAndPop = () =>
        {
            Console.WriteLine($"Task started on {Task.CurrentId}");

            int item;
            for (int i = 0; i < items; i++)
                stack.Push(i);
            for (int i = 0; i < items; i++)
                stack.TryPop(out item);

            Console.WriteLine($"Task ended on {Task.CurrentId}");
        };

        // Spin up five concurrent tasks of the action
        var tasks = new Task[5];
        for (int i = 0; i < tasks.Length; i++)
            tasks[i] = Task.Factory.StartNew(pushAndPop);

        // Wait for all the tasks to finish up
        await Task.WhenAll(tasks);

        if (!stack.IsEmpty)
        {
            Console.WriteLine("Did not take all the items off the stack");
        }
    }
}
Imports System.Collections.Concurrent
Imports System.Threading.Tasks

Class Example
    ' Demonstrates:
    '   ConcurrentStack<T>.Push();
    '   ConcurrentStack<T>.TryPeek();
    '   ConcurrentStack<T>.TryPop();
    '   ConcurrentStack<T>.Clear();
    '   ConcurrentStack<T>.IsEmpty;
    Shared Sub Main()
        Dim items As Integer = 10000
        Dim stack As ConcurrentStack(Of Integer) = New ConcurrentStack(Of Integer)()

        ' Create an action to push items onto the stack
        Dim pusher As Action = Function()
                                   For i As Integer = 0 To items - 1
                                       stack.Push(i)
                                   Next
                               End Function

        ' Run the action once
        pusher()

        Dim result As Integer = Nothing

        If stack.TryPeek(result) Then
            Console.WriteLine($"TryPeek() saw {result} on top of the stack.")
        Else
            Console.WriteLine("Could not peek most recently added number.")
        End If

        ' Empty the stack
        stack.Clear()

        If stack.IsEmpty Then
            Console.WriteLine("Cleared the stack.")
        End If

        ' Create an action to push and pop items
        Dim pushAndPop As Action = Function()
                                       Console.WriteLine($"Task started on {Task.CurrentId}")
                                       Dim item As Integer

                                       For i As Integer = 0 To items - 1
                                           stack.Push(i)
                                       Next

                                       For i As Integer = 0 To items - 1
                                           stack.TryPop(item)
                                       Next

                                       Console.WriteLine($"Task ended on {Task.CurrentId}")
                                   End Function

        ' Spin up five concurrent tasks of the action
        Dim tasks = New Task(4) {}
        For i As Integer = 0 To tasks.Length - 1
            tasks(i) = Task.Factory.StartNew(pushAndPop)
        Next

        ' Wait for all the tasks to finish up
        Task.WaitAll(tasks)

        If Not stack.IsEmpty Then
            Console.WriteLine("Did not take all the items off the stack")
        End If
    End Sub
End Class

下面的示例演示如何使用ConcurrentStack<T>来推送和弹出项目范围:The following example shows how to use a ConcurrentStack<T> to push and pop ranges of items:

using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

class Example
{
    // Demonstrates:
    //      ConcurrentStack<T>.PushRange();
    //      ConcurrentStack<T>.TryPopRange();
    static async Task Main()
    {
        int numParallelTasks = 4;
        int numItems = 1000;
        var stack = new ConcurrentStack<int>();

        // Push a range of values onto the stack concurrently
        await Task.WhenAll(Enumerable.Range(0, numParallelTasks).Select(i => Task.Factory.StartNew((state) =>
        {
            // state = i * numItems
            int index = (int)state;
            int[] array = new int[numItems];
            for (int j = 0; j < numItems; j++)
            {
                array[j] = index + j;
            }

            Console.WriteLine($"Pushing an array of ints from {array[0]} to {array[numItems - 1]}");
            stack.PushRange(array);
        }, i * numItems, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default)).ToArray());


        int numTotalElements = 4 * numItems;
        int[] resultBuffer = new int[numTotalElements];
        await Task.WhenAll(Enumerable.Range(0, numParallelTasks).Select(i => Task.Factory.StartNew(obj =>
        {
            int index = (int)obj;
            int result = stack.TryPopRange(resultBuffer, index, numItems);

            Console.WriteLine($"TryPopRange expected {numItems}, got {result}.");

        }, i * numItems, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default)).ToArray());

        for (int i = 0; i < numParallelTasks; i++)
        {
            // Create a sequence we expect to see from the stack taking the last number of the range we inserted
            var expected = Enumerable.Range(resultBuffer[i*numItems + numItems - 1], numItems);

            // Take the range we inserted, reverse it, and compare to the expected sequence
            var areEqual = expected.SequenceEqual(resultBuffer.Skip(i * numItems).Take(numItems).Reverse());
            if (areEqual)
            {
                Console.WriteLine($"Expected a range of {expected.First()} to {expected.Last()}. Got {resultBuffer[i * numItems + numItems - 1]} to {resultBuffer[i * numItems]}");
            }
            else
            {
                Console.WriteLine($"Unexpected consecutive ranges.");
            }   
        }
    }
}
Imports System.Collections.Concurrent
Imports System.Linq
Imports System.Threading
Imports System.Threading.Tasks

Class Example
    ' Demonstrates:
    '   ConcurrentStack<T>.PushRange();
    '   ConcurrentStack<T>.TryPopRange();
    Shared Sub Main()
        Dim numParallelTasks As Integer = 4
        Dim numItems As Integer = 1000
        Dim stack = New ConcurrentStack(Of Integer)()

        ' Push a range of values onto the stack concurrently
        Task.WaitAll(Enumerable.Range(0, numParallelTasks).[Select](
                     Function(i) Task.Factory.StartNew(
                        Function(state)
                            Dim index As Integer = CInt(state)
                            Dim array As Integer() = New Integer(numItems - 1) {}

                            For j As Integer = 0 To numItems - 1
                                array(j) = index + j
                            Next

                            Console.WriteLine($"Pushing an array of ints from {array(0)} to {array(numItems - 1)}")
                            stack.PushRange(array)
                        End Function, i * numItems, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.[Default])).ToArray())


        Dim numTotalElements As Integer = 4 * numItems
        Dim resultBuffer As Integer() = New Integer(numTotalElements - 1) {}
        Task.WaitAll(Enumerable.Range(0, numParallelTasks).[Select](
                     Function(i) Task.Factory.StartNew(
                        Function(obj)
                            Dim index As Integer = CInt(obj)
                            Dim result As Integer = stack.TryPopRange(resultBuffer, index, numItems)
                            Console.WriteLine($"TryPopRange expected {numItems}, got {result}.")
                        End Function, i * numItems, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.[Default])).ToArray())

        For i As Integer = 0 To numParallelTasks - 1
            ' Create a sequence we expect to see from the stack taking the last number of the range we inserted
            Dim expected = Enumerable.Range(resultBuffer(i * numItems + numItems - 1), numItems)

            ' Take the range we inserted, reverse it, and compare to the expected sequence
            Dim areEqual = expected.SequenceEqual(resultBuffer.Skip(i * numItems).Take(numItems).Reverse())

            If areEqual Then
                Console.WriteLine($"Expected a range of {expected.First()} to {expected.Last()}. Got {resultBuffer(i * numItems + numItems - 1)} to {resultBuffer(i * numItems)}")
            Else
                Console.WriteLine($"Unexpected consecutive ranges.")
            End If
        Next
    End Sub
End Class

注解

备注

ConcurrentStack<T>实现从开始.NET Framework 4.6.NET Framework 4.6ConcurrentStack<T>接口; 在以前版本的 .NET Framework 中,类未实现此接口。 IReadOnlyCollection<T>ConcurrentStack<T> implements the IReadOnlyCollection<T> interface starting with the .NET Framework 4.6.NET Framework 4.6; in previous versions of the .NET Framework, the ConcurrentStack<T> class did not implement this interface.

ConcurrentStack<T>提供几个主要操作:ConcurrentStack<T> provides a few main operations:

构造函数

ConcurrentStack<T>() ConcurrentStack<T>() ConcurrentStack<T>() ConcurrentStack<T>()

初始化 ConcurrentStack<T> 类的新实例。Initializes a new instance of the ConcurrentStack<T> class.

ConcurrentStack<T>(IEnumerable<T>) ConcurrentStack<T>(IEnumerable<T>) ConcurrentStack<T>(IEnumerable<T>) ConcurrentStack<T>(IEnumerable<T>)

初始化 ConcurrentStack<T> 类的新实例,该类包含从指定集合中复制的元素Initializes a new instance of the ConcurrentStack<T> class that contains elements copied from the specified collection

属性

Count Count Count Count

获取 ConcurrentStack<T> 中包含的元素数。Gets the number of elements contained in the ConcurrentStack<T>.

IsEmpty IsEmpty IsEmpty IsEmpty

获取一个指示 ConcurrentStack<T> 是否为空的值。Gets a value that indicates whether the ConcurrentStack<T> is empty.

方法

Clear() Clear() Clear() Clear()

ConcurrentStack<T> 中移除所有对象。Removes all objects from the ConcurrentStack<T>.

CopyTo(T[], Int32) CopyTo(T[], Int32) CopyTo(T[], Int32) CopyTo(T[], Int32)

从指定数组索引开始将 ConcurrentStack<T> 元素复制到现有一维 Array 中。Copies the ConcurrentStack<T> elements to an existing one-dimensional Array, starting at the specified array index.

Equals(Object) Equals(Object) Equals(Object) Equals(Object)

确定指定的对象是否等于当前对象。Determines whether the specified object is equal to the current object.

(Inherited from Object)
GetEnumerator() GetEnumerator() GetEnumerator() GetEnumerator()

返回循环访问 ConcurrentStack<T> 的枚举数。Returns an enumerator that iterates through the ConcurrentStack<T>.

GetHashCode() GetHashCode() GetHashCode() GetHashCode()

作为默认哈希函数。Serves as the default hash function.

(Inherited from Object)
GetType() GetType() GetType() GetType()

获取当前实例的 TypeGets the Type of the current instance.

(Inherited from Object)
MemberwiseClone() MemberwiseClone() MemberwiseClone() MemberwiseClone()

创建当前 Object 的浅表副本。Creates a shallow copy of the current Object.

(Inherited from Object)
Push(T) Push(T) Push(T) Push(T)

将对象插入 ConcurrentStack<T> 的顶部。Inserts an object at the top of the ConcurrentStack<T>.

PushRange(T[]) PushRange(T[]) PushRange(T[]) PushRange(T[])

自动将多个对象插入 ConcurrentStack<T> 的顶部。Inserts multiple objects at the top of the ConcurrentStack<T> atomically.

PushRange(T[], Int32, Int32) PushRange(T[], Int32, Int32) PushRange(T[], Int32, Int32) PushRange(T[], Int32, Int32)

自动将多个对象插入 ConcurrentStack<T> 的顶部。Inserts multiple objects at the top of the ConcurrentStack<T> atomically.

ToArray() ToArray() ToArray() ToArray()

ConcurrentStack<T> 中存储的项复制到新数组。Copies the items stored in the ConcurrentStack<T> to a new array.

ToString() ToString() ToString() ToString()

返回表示当前对象的字符串。Returns a string that represents the current object.

(Inherited from Object)
TryPeek(T) TryPeek(T) TryPeek(T) TryPeek(T)

尝试返回 ConcurrentStack<T> 顶部的对象但不将其移除。Attempts to return an object from the top of the ConcurrentStack<T> without removing it.

TryPop(T) TryPop(T) TryPop(T) TryPop(T)

尝试弹出并返回 ConcurrentStack<T> 顶部的对象。Attempts to pop and return the object at the top of the ConcurrentStack<T>.

TryPopRange(T[]) TryPopRange(T[]) TryPopRange(T[]) TryPopRange(T[])

尝试自动弹出并返回 ConcurrentStack<T> 顶部的多个对象。Attempts to pop and return multiple objects from the top of the ConcurrentStack<T> atomically.

TryPopRange(T[], Int32, Int32) TryPopRange(T[], Int32, Int32) TryPopRange(T[], Int32, Int32) TryPopRange(T[], Int32, Int32)

尝试自动弹出并返回 ConcurrentStack<T> 顶部的多个对象。Attempts to pop and return multiple objects from the top of the ConcurrentStack<T> atomically.

显式界面实现

ICollection.CopyTo(Array, Int32) ICollection.CopyTo(Array, Int32) ICollection.CopyTo(Array, Int32) ICollection.CopyTo(Array, Int32)

从特定的 ICollection 索引开始,将 Array 的元素复制到一个 Array 中。Copies the elements of the ICollection to an Array, starting at a particular Array index.

ICollection.IsSynchronized ICollection.IsSynchronized ICollection.IsSynchronized ICollection.IsSynchronized

获取一个值,该值指示对 ICollection 的访问是否与 SyncRoot 保持同步。Gets a value indicating whether access to the ICollection is synchronized with the SyncRoot.

ICollection.SyncRoot ICollection.SyncRoot ICollection.SyncRoot ICollection.SyncRoot

获取可用于同步对 ICollection 的访问的对象。Gets an object that can be used to synchronize access to the ICollection. 不支持此属性。This property is not supported.

IEnumerable.GetEnumerator() IEnumerable.GetEnumerator() IEnumerable.GetEnumerator() IEnumerable.GetEnumerator()

返回循环访问集合的枚举数。Returns an enumerator that iterates through a collection.

IProducerConsumerCollection<T>.TryAdd(T) IProducerConsumerCollection<T>.TryAdd(T) IProducerConsumerCollection<T>.TryAdd(T) IProducerConsumerCollection<T>.TryAdd(T)

尝试将一个对象添加到 IProducerConsumerCollection<T> 中。Attempts to add an object to the IProducerConsumerCollection<T>.

IProducerConsumerCollection<T>.TryTake(T) IProducerConsumerCollection<T>.TryTake(T) IProducerConsumerCollection<T>.TryTake(T) IProducerConsumerCollection<T>.TryTake(T)

尝试从 IProducerConsumerCollection<T> 中移除并返回一个对象。Attempts to remove and return an object from the IProducerConsumerCollection<T>.

扩展方法

CopyToDataTable<T>(IEnumerable<T>) CopyToDataTable<T>(IEnumerable<T>) CopyToDataTable<T>(IEnumerable<T>) CopyToDataTable<T>(IEnumerable<T>)

在给定其泛型参数 TDataTable 的输入 DataRow 对象的情况下,返回包含 IEnumerable<T> 对象副本的 DataRowReturns a DataTable that contains copies of the DataRow objects, given an input IEnumerable<T> object where the generic parameter T is DataRow.

CopyToDataTable<T>(IEnumerable<T>, DataTable, LoadOption) CopyToDataTable<T>(IEnumerable<T>, DataTable, LoadOption) CopyToDataTable<T>(IEnumerable<T>, DataTable, LoadOption) CopyToDataTable<T>(IEnumerable<T>, DataTable, LoadOption)

在给定其泛型参数 TDataRow 的输入 DataTable 对象的情况下,将 IEnumerable<T> 对象复制到指定的 DataRowCopies DataRow objects to the specified DataTable, given an input IEnumerable<T> object where the generic parameter T is DataRow.

CopyToDataTable<T>(IEnumerable<T>, DataTable, LoadOption, FillErrorEventHandler) CopyToDataTable<T>(IEnumerable<T>, DataTable, LoadOption, FillErrorEventHandler) CopyToDataTable<T>(IEnumerable<T>, DataTable, LoadOption, FillErrorEventHandler) CopyToDataTable<T>(IEnumerable<T>, DataTable, LoadOption, FillErrorEventHandler)

在给定其泛型参数 TDataRow 的输入 DataTable 对象的情况下,将 IEnumerable<T> 对象复制到指定的 DataRowCopies DataRow objects to the specified DataTable, given an input IEnumerable<T> object where the generic parameter T is DataRow.

Cast<TResult>(IEnumerable) Cast<TResult>(IEnumerable) Cast<TResult>(IEnumerable) Cast<TResult>(IEnumerable)

IEnumerable 的元素强制转换为指定的类型。Casts the elements of an IEnumerable to the specified type.

OfType<TResult>(IEnumerable) OfType<TResult>(IEnumerable) OfType<TResult>(IEnumerable) OfType<TResult>(IEnumerable)

根据指定类型筛选 IEnumerable 的元素。Filters the elements of an IEnumerable based on a specified type.

AsParallel(IEnumerable) AsParallel(IEnumerable) AsParallel(IEnumerable) AsParallel(IEnumerable)

启用查询的并行化。Enables parallelization of a query.

AsQueryable(IEnumerable) AsQueryable(IEnumerable) AsQueryable(IEnumerable) AsQueryable(IEnumerable)

IEnumerable 转换为 IQueryableConverts an IEnumerable to an IQueryable.

Ancestors<T>(IEnumerable<T>) Ancestors<T>(IEnumerable<T>) Ancestors<T>(IEnumerable<T>) Ancestors<T>(IEnumerable<T>)

返回元素集合,其中包含源集合中每个节点的上级。Returns a collection of elements that contains the ancestors of every node in the source collection.

Ancestors<T>(IEnumerable<T>, XName) Ancestors<T>(IEnumerable<T>, XName) Ancestors<T>(IEnumerable<T>, XName) Ancestors<T>(IEnumerable<T>, XName)

返回经过筛选的元素集合,其中包含源集合中每个节点的上级。Returns a filtered collection of elements that contains the ancestors of every node in the source collection. 集合中仅包括具有匹配 XName 的元素。Only elements that have a matching XName are included in the collection.

DescendantNodes<T>(IEnumerable<T>) DescendantNodes<T>(IEnumerable<T>) DescendantNodes<T>(IEnumerable<T>) DescendantNodes<T>(IEnumerable<T>)

返回源集合中每个文档和元素的子代节点的集合。Returns a collection of the descendant nodes of every document and element in the source collection.

Descendants<T>(IEnumerable<T>) Descendants<T>(IEnumerable<T>) Descendants<T>(IEnumerable<T>) Descendants<T>(IEnumerable<T>)

返回元素集合,其中包含源集合中每个元素和文档的子代元素。Returns a collection of elements that contains the descendant elements of every element and document in the source collection.

Descendants<T>(IEnumerable<T>, XName) Descendants<T>(IEnumerable<T>, XName) Descendants<T>(IEnumerable<T>, XName) Descendants<T>(IEnumerable<T>, XName)

返回经过筛选的元素集合,其中包含源集合中每个元素和文档的子代元素。Returns a filtered collection of elements that contains the descendant elements of every element and document in the source collection. 集合中仅包括具有匹配 XName 的元素。Only elements that have a matching XName are included in the collection.

Elements<T>(IEnumerable<T>) Elements<T>(IEnumerable<T>) Elements<T>(IEnumerable<T>) Elements<T>(IEnumerable<T>)

返回源集合中每个元素和文档的子元素的集合。Returns a collection of the child elements of every element and document in the source collection.

Elements<T>(IEnumerable<T>, XName) Elements<T>(IEnumerable<T>, XName) Elements<T>(IEnumerable<T>, XName) Elements<T>(IEnumerable<T>, XName)

返回源集合中经过筛选的每个元素和文档的子元素集合。Returns a filtered collection of the child elements of every element and document in the source collection. 集合中仅包括具有匹配 XName 的元素。Only elements that have a matching XName are included in the collection.

InDocumentOrder<T>(IEnumerable<T>) InDocumentOrder<T>(IEnumerable<T>) InDocumentOrder<T>(IEnumerable<T>) InDocumentOrder<T>(IEnumerable<T>)

返回节点集合(其中包含源集合中的所有节点),并按文档顺序排列。Returns a collection of nodes that contains all nodes in the source collection, sorted in document order.

Nodes<T>(IEnumerable<T>) Nodes<T>(IEnumerable<T>) Nodes<T>(IEnumerable<T>) Nodes<T>(IEnumerable<T>)

返回源集合中每个文档和元素的子节点集合。Returns a collection of the child nodes of every document and element in the source collection.

Remove<T>(IEnumerable<T>) Remove<T>(IEnumerable<T>) Remove<T>(IEnumerable<T>) Remove<T>(IEnumerable<T>)

将源集合中的每个节点从其父节点中移除。Removes every node in the source collection from its parent node.

适用于

线程安全性

的所有公共和受保护ConcurrentStack<T>的成员都是线程安全的, 可从多个线程并发使用。All public and protected members of ConcurrentStack<T> are thread-safe and may be used concurrently from multiple threads.

另请参阅