ConcurrentStack<T> 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
表示線程安全最後一次傳入 (LIFO) 集合。
generic <typename T>
public ref class ConcurrentStack : System::Collections::Concurrent::IProducerConsumerCollection<T>, System::Collections::Generic::IEnumerable<T>, System::Collections::Generic::IReadOnlyCollection<T>, System::Collections::ICollection
generic <typename T>
public ref class ConcurrentStack : System::Collections::Concurrent::IProducerConsumerCollection<T>, System::Collections::Generic::IEnumerable<T>
generic <typename T>
public ref class ConcurrentStack : System::Collections::Concurrent::IProducerConsumerCollection<T>, System::Collections::Generic::IEnumerable<T>, System::Collections::Generic::IReadOnlyCollection<T>
generic <typename T>
public ref class ConcurrentStack : System::Collections::Concurrent::IProducerConsumerCollection<T>, System::Collections::Generic::IEnumerable<T>, System::Collections::ICollection
public class ConcurrentStack<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.ICollection
[System.Serializable]
public class ConcurrentStack<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>
[System.Serializable]
public class ConcurrentStack<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>
public class ConcurrentStack<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.ICollection
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 seq<'T>
interface IEnumerable
interface ICollection
interface IReadOnlyCollection<'T>
[<System.Serializable>]
type ConcurrentStack<'T> = class
interface IProducerConsumerCollection<'T>
interface seq<'T>
interface ICollection
interface IEnumerable
[<System.Serializable>]
type ConcurrentStack<'T> = class
interface IProducerConsumerCollection<'T>
interface seq<'T>
interface IEnumerable
interface ICollection
interface IReadOnlyCollection<'T>
type ConcurrentStack<'T> = class
interface IProducerConsumerCollection<'T>
interface seq<'T>
interface ICollection
interface IEnumerable
Public Class ConcurrentStack(Of T)
Implements ICollection, IEnumerable(Of T), IProducerConsumerCollection(Of T), IReadOnlyCollection(Of T)
Public Class ConcurrentStack(Of T)
Implements IEnumerable(Of T), IProducerConsumerCollection(Of T)
Public Class ConcurrentStack(Of T)
Implements IEnumerable(Of T), IProducerConsumerCollection(Of T), IReadOnlyCollection(Of T)
Public Class ConcurrentStack(Of T)
Implements ICollection, IEnumerable(Of T), IProducerConsumerCollection(Of T)
類型參數
- T
堆疊中包含的專案型別。
- 繼承
-
ConcurrentStack<T>
- 屬性
- 實作
範例
下列範例示範如何使用 ConcurrentStack<T> 來推送和快顯個別專案:
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");
}
}
}
open System
open System.Collections.Concurrent
open System.Threading.Tasks
// Demonstrates:
// ConcurrentStack<T>.Push();
// ConcurrentStack<T>.TryPeek();
// ConcurrentStack<T>.TryPop();
// ConcurrentStack<T>.Clear();
// ConcurrentStack<T>.IsEmpty;
let main =
task {
let items = 10000
let stack = ConcurrentStack<int>()
// Create an action to push items onto the stack
let pusher =
Action(fun () ->
for i = 0 to items - 1 do
stack.Push i)
// Run the action once
pusher.Invoke()
let mutable result = 0
if stack.TryPeek &result then
printfn $"TryPeek() saw {result} on top of the stack."
else
printfn "Could not peek most recently added number."
// Empty the stack
stack.Clear()
if stack.IsEmpty then
printfn "Cleared the stack."
// Create an action to push and pop items
let pushAndPop =
Action(fun () ->
printfn $"Task started on {Task.CurrentId}"
let mutable item = 0
for i = 0 to items - 1 do
stack.Push i
for i = 0 to items - 1 do
stack.TryPop &item |> ignore
printfn $"Task ended on {Task.CurrentId}")
// Spin up five concurrent tasks of the action
let tasks =
[| for i = 0 to 4 do
Task.Run pushAndPop |]
// Wait for all the tasks to finish up
do! Task.WhenAll tasks
if not stack.IsEmpty then
printfn "Did not take all the items off the stack"
}
main.Wait()
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> 來推送和快顯項目範圍:
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.");
}
}
}
}
open System.Collections.Concurrent
open System.Linq
open System.Threading
open System.Threading.Tasks
// Demonstrates:
// ConcurrentStack<T>.PushRange();
// ConcurrentStack<T>.TryPopRange();
let main =
task {
let numParallelTasks = 4
let numItems = 1000
let stack = ConcurrentStack<int>()
// Push a range of values onto the stack concurrently
let! _ = Task.WhenAll(Enumerable.Range(0, numParallelTasks).Select(fun i ->
Task.Factory.StartNew((fun state ->
// state = i * numItems
let index: int = unbox state
let array =
[| for j in 0 .. numItems - 1 do
index + j |]
printfn $"Pushing an array of ints from {array[0]} to {array[numItems - 1]}"
stack.PushRange array
), i * numItems, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default)).ToArray())
let numTotalElements = 4 * numItems
let resultBuffer = Array.zeroCreate numTotalElements
let! _ = Task.WhenAll(Enumerable.Range(0, numParallelTasks).Select(fun i ->
Task.Factory.StartNew((fun obj ->
let index = unbox obj
let result = stack.TryPopRange(resultBuffer, index, numItems)
printfn $"TryPopRange expected {numItems}, got {result}."
), i * numItems, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default)).ToArray())
for i = 0 to numParallelTasks - 1 do
// Create a sequence we expect to see from the stack taking the last number of the range we inserted
let expected = Enumerable.Range(resultBuffer[i*numItems + numItems - 1], numItems)
// Take the range we inserted, reverse it, and compare to the expected sequence
let areEqual = expected.SequenceEqual(resultBuffer.Skip(i * numItems).Take(numItems).Reverse())
if areEqual then
printfn $"Expected a range of {expected.First()} to {expected.Last()}. Got {resultBuffer[i * numItems + numItems - 1]} to {resultBuffer[i * numItems]}"
else
printfn $"Unexpected consecutive ranges."
}
main.Wait()
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 開始的 IReadOnlyCollection<T> 介面;在舊版 .NET Framework 中,ConcurrentStack<T> 類別未實作這個介面。
ConcurrentStack<T> 提供一些主要作業:
Push 會在 ConcurrentStack<T>頂端插入專案。
TryPop 會從 ConcurrentStack<T>頂端移除專案,或如果無法移除專案,則會傳回
false
。TryPeek 傳回位於 ConcurrentStack<T> 頂端但不會從 ConcurrentStack<T>移除的專案。
TryPopRange 和 PushRange 方法可在單一作業中有效推送和彈出多個元素。
建構函式
ConcurrentStack<T>() |
初始化 ConcurrentStack<T> 類別的新實例。 |
ConcurrentStack<T>(IEnumerable<T>) |
初始化 ConcurrentStack<T> 類別的新實例,這個實例包含從指定集合複製的專案。 |
屬性
Count |
取得包含在 ConcurrentStack<T>中的項目數目。 |
IsEmpty |
取得值,這個值表示 ConcurrentStack<T> 是否為空白。 |
方法
Clear() |
從 ConcurrentStack<T>移除所有物件。 |
CopyTo(T[], Int32) |
從指定的陣列索引開始,將 ConcurrentStack<T> 專案複製到現有的一維 Array。 |
Equals(Object) |
判斷指定的物件是否等於目前的物件。 (繼承來源 Object) |
GetEnumerator() |
傳回逐一查看 ConcurrentStack<T>的列舉值。 |
GetHashCode() |
做為預設哈希函式。 (繼承來源 Object) |
GetType() |
取得目前實例的 Type。 (繼承來源 Object) |
MemberwiseClone() |
建立目前 Object的淺層複本。 (繼承來源 Object) |
Push(T) |
在 ConcurrentStack<T>頂端插入物件。 |
PushRange(T[]) |
以不可部分完成的方式在 ConcurrentStack<T> 頂端插入多個物件。 |
PushRange(T[], Int32, Int32) |
以不可部分完成的方式在 ConcurrentStack<T> 頂端插入多個物件。 |
ToArray() |
將儲存在 ConcurrentStack<T> 中的項目複製到新的陣列。 |
ToString() |
傳回表示目前 物件的字串。 (繼承來源 Object) |
TryPeek(T) |
嘗試從 ConcurrentStack<T> 頂端傳回物件,而不移除它。 |
TryPop(T) |
嘗試快顯並傳回位於 ConcurrentStack<T>頂端的物件。 |
TryPopRange(T[]) |
嘗試從 ConcurrentStack<T> 不可部分完成的方式從頂端快顯並傳回多個物件。 |
TryPopRange(T[], Int32, Int32) |
嘗試從 ConcurrentStack<T> 不可部分完成的方式從頂端快顯並傳回多個物件。 |
明確介面實作
ICollection.CopyTo(Array, Int32) |
從特定 Array 索引開始,將 ICollection 的專案複製到 Array。 |
ICollection.IsSynchronized |
取得值,指出存取 ICollection 是否與 SyncRoot 同步。 |
ICollection.SyncRoot |
取得對象,這個物件可用來同步存取 ICollection。 不支援這個屬性。 |
IEnumerable.GetEnumerator() |
傳回逐一查看集合的列舉值。 |
IProducerConsumerCollection<T>.TryAdd(T) |
試著將 物件加入至 IProducerConsumerCollection<T>。 |
IProducerConsumerCollection<T>.TryTake(T) |
嘗試從 IProducerConsumerCollection<T>移除並傳回 物件。 |
擴充方法
適用於
執行緒安全性
ConcurrentStack<T> 的所有公用和受保護成員都是安全線程,而且可以從多個線程同時使用。