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 メソッドは、1 回の操作で複数の要素を効率的にプッシュおよびポップします。
コンストラクター
ConcurrentStack<T>() |
ConcurrentStack<T> クラスの新しいインスタンスを初期化します。 |
ConcurrentStack<T>(IEnumerable<T>) |
指定したコレクションからコピーされた要素を含む ConcurrentStack<T> クラスの新しいインスタンスを初期化します。 |
プロパティ
Count |
ConcurrentStack<T>に含まれる要素の数を取得します。 |
IsEmpty |
ConcurrentStack<T> が空かどうかを示す値を取得します。 |
メソッド
Clear() |
ConcurrentStack<T>からすべてのオブジェクトを削除します。 |
CopyTo(T[], Int32) |
ConcurrentStack<T> 要素を、指定した配列インデックスから始まる既存の 1 次元 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> のすべてのパブリック メンバーと保護されたメンバーはスレッド セーフであり、複数のスレッドから同時に使用できます。
こちらもご覧ください
.NET