SemaphoreSlim SemaphoreSlim SemaphoreSlim SemaphoreSlim Class

定義

リソースまたはリソースのプールに同時にアクセスできるスレッドの数を制限する Semaphore の軽量版を表します。Represents a lightweight alternative to Semaphore that limits the number of threads that can access a resource or pool of resources concurrently.

public ref class SemaphoreSlim : IDisposable
[System.Runtime.InteropServices.ComVisible(false)]
public class SemaphoreSlim : IDisposable
type SemaphoreSlim = class
    interface IDisposable
Public Class SemaphoreSlim
Implements IDisposable
継承
SemaphoreSlimSemaphoreSlimSemaphoreSlimSemaphoreSlim
属性
実装

次の例では、3 つのスレッドの最大数、0 個のスレッドの最初の数と、セマフォを作成します。The following example creates a semaphore with a maximum count of three threads and an initial count of zero threads. 例では、セマフォの待機をブロックの 5 つのタスクを開始します。The example starts five tasks, all of which block waiting for the semaphore. メイン スレッドの呼び出し、Release(Int32)オーバー ロードにより、セマフォに入るための 3 つのタスクを最大容量にセマフォのカウントを増やす。The main thread calls the Release(Int32) overload to increase the semaphore count to its maximum, which allows three tasks to enter the semaphore. セマフォがリリースされるたびに、前のセマフォのカウントが表示されます。Each time the semaphore is released, the previous semaphore count is displayed. コンソール メッセージ追跡セマフォを使用します。Console messages track semaphore use. 各スレッドの出力を読みやすくするために、シミュレートされた動作の間隔が若干増加します。The simulated work interval is increased slightly for each thread to make the output easier to read.

using System;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
    private static SemaphoreSlim semaphore;
    // A padding interval to make the output more orderly.
    private static int padding;

    public static void Main()
    {
        // Create the semaphore.
        semaphore = new SemaphoreSlim(0, 3);
        Console.WriteLine("{0} tasks can enter the semaphore.",
                          semaphore.CurrentCount);
        Task[] tasks = new Task[5];
        
        // Create and start five numbered tasks.
        for(int i = 0; i <= 4; i++)
        {
            tasks[i] = Task.Run( () => {
            // Each task begins by requesting the semaphore.
            Console.WriteLine("Task {0} begins and waits for the semaphore.",
                              Task.CurrentId);
            semaphore.Wait();

            Interlocked.Add(ref padding, 100);

            Console.WriteLine("Task {0} enters the semaphore.", Task.CurrentId);

            // The task just sleeps for 1+ seconds.
            Thread.Sleep(1000 + padding);

            Console.WriteLine("Task {0} releases the semaphore; previous count: {1}.",
                              Task.CurrentId, semaphore.Release()); } );
        }

        // Wait for half a second, to allow all the tasks to start and block.
        Thread.Sleep(500);

        // Restore the semaphore count to its maximum value.
        Console.Write("Main thread calls Release(3) --> ");
        semaphore.Release(3);
        Console.WriteLine("{0} tasks can enter the semaphore.",
                          semaphore.CurrentCount);
        // Main thread waits for the tasks to complete.
        Task.WaitAll(tasks);
        
        Console.WriteLine("Main thread exits.");
    }
}
// The example displays output like the following:
//       0 tasks can enter the semaphore.
//       Task 1 begins and waits for the semaphore.
//       Task 5 begins and waits for the semaphore.
//       Task 2 begins and waits for the semaphore.
//       Task 4 begins and waits for the semaphore.
//       Task 3 begins and waits for the semaphore.
//       Main thread calls Release(3) --> 3 tasks can enter the semaphore.
//       Task 4 enters the semaphore.
//       Task 1 enters the semaphore.
//       Task 3 enters the semaphore.
//       Task 4 releases the semaphore; previous count: 0.
//       Task 2 enters the semaphore.
//       Task 1 releases the semaphore; previous count: 0.
//       Task 3 releases the semaphore; previous count: 0.
//       Task 5 enters the semaphore.
//       Task 2 releases the semaphore; previous count: 1.
//       Task 5 releases the semaphore; previous count: 2.
//       Main thread exits.
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Private semaphore As SemaphoreSlim
    ' A padding interval to make the output more orderly.
    Private padding As Integer

   Public Sub Main()
      ' Create the semaphore.
      semaphore = New SemaphoreSlim(0, 3)
      Console.WriteLine("{0} tasks can enter the semaphore.",
                        semaphore.CurrentCount)
      Dim tasks(4) As Task

      ' Create and start five numbered tasks.
      For i As Integer = 0 To 4
         tasks(i) = Task.Run(
            Sub()
               ' Each task begins by requesting the semaphore.
               Console.WriteLine("Task {0} begins and waits for the semaphore.",
                              Task.CurrentId)
               semaphore.Wait()

               Interlocked.Add(padding, 100)

               Console.WriteLine("Task {0} enters the semaphore.", Task.CurrentId)

               ' The task just sleeps for 1+ seconds.
               Thread.Sleep(1000 + padding)

               Console.WriteLine("Task {0} releases the semaphore previous count: {1}.",
                                 Task.CurrentId, semaphore.Release())
            End Sub )
      Next

      ' Wait for half a second, to allow all the tasks to start and block.
      Thread.Sleep(500)

      ' Restore the semaphore count to its maximum value.
      Console.Write("Main thread calls Release(3) --> ")
      semaphore.Release(3)
      Console.WriteLine("{0} tasks can enter the semaphore.",
                        semaphore.CurrentCount)
      ' Main thread waits for the tasks to complete.
      Task.WaitAll(tasks)

      Console.WriteLine("Main thread exits.")
   End Sub
End Module
' The example displays output like the following:
'       0 tasks can enter the semaphore.
'       Task 1 begins and waits for the semaphore.
'       Task 5 begins and waits for the semaphore.
'       Task 2 begins and waits for the semaphore.
'       Task 4 begins and waits for the semaphore.
'       Task 3 begins and waits for the semaphore.
'       Main thread calls Release(3) --> 3 tasks can enter the semaphore.
'       Task 4 enters the semaphore.
'       Task 1 enters the semaphore.
'       Task 3 enters the semaphore.
'       Task 4 releases the semaphore; previous count: 0.
'       Task 2 enters the semaphore.
'       Task 1 releases the semaphore; previous count: 0.
'       Task 3 releases the semaphore; previous count: 0.
'       Task 5 enters the semaphore.
'       Task 2 releases the semaphore; previous count: 1.
'       Task 5 releases the semaphore; previous count: 2.
'       Main thread exits.

注釈

セマフォは次の 2 つの種類: ローカル セマフォおよび名前付きシステム セマフォです。Semaphores are of two types: local semaphores and named system semaphores. 前者は、アプリに対してローカルです。The former is local to an app. 後者の場合は、オペレーティング システム全体の表示とはプロセス間の同期に適しています。The latter is visible throughout the operating system and is suitable for inter-process synchronization. SemaphoreSlimは軽量の代わりに、Semaphoreクラスを Windows カーネルのセマフォを使用しません。The SemaphoreSlim is a lightweight alternative to the Semaphore class that doesn't use Windows kernel semaphores. 異なり、Semaphoreクラス、SemaphoreSlimクラスは、名前付きシステム セマフォをサポートしていません。Unlike the Semaphore class, the SemaphoreSlim class doesn't support named system semaphores. これは、ローカル セマフォのみとして使用できます。You can use it as a local semaphore only. SemaphoreSlimクラスは、1 つのアプリ内での同期の推奨されるセマフォです。The SemaphoreSlim class is the recommended semaphore for synchronization within a single app.

軽量のセマフォは、ローカル アプリケーションにあるリソースのプールへのアクセスを制御します。A lightweight semaphore controls access to a pool of resources that is local to your application. セマフォをインスタンス化するときは、セマフォを同時に入力できるスレッドの最大数を指定できます。When you instantiate a semaphore, you can specify the maximum number of threads that can enter the semaphore concurrently. また、セマフォを同時に入力できるスレッドの初期数を指定します。You also specify the initial number of threads that can enter the semaphore concurrently. これには、セマフォのカウントを定義します。This defines the semaphore's count.

カウントがデクリメント、スレッドがセマフォに入るたびにし、毎回増加、スレッドがセマフォを解放します。The count is decremented each time a thread enters the semaphore, and incremented each time a thread releases the semaphore. スレッドでは、セマフォに入るを呼び出すの 1 つ、WaitまたはWaitAsyncオーバー ロードします。To enter the semaphore, a thread calls one of the Wait or WaitAsync overloads. 呼び出しのいずれかのセマフォを解放する、Releaseオーバー ロードします。To release the semaphore, it calls one of the Release overloads. カウントが 0、後続の呼び出しのいずれかに達したとき、Waitメソッドは、他のスレッドがセマフォを解放するまでブロックします。When the count reaches zero, subsequent calls to one of the Wait methods block until other threads release the semaphore. 複数のスレッドがブロックされている場合は、保証された順序はありません、FIFO や LIFO などをスレッドがセマフォに入るときに制御します。If multiple threads are blocked, there is no guaranteed order, such as FIFO or LIFO, that controls when threads enter the semaphore.

リソースを保護する、セマフォを使用するコードの基本的な構造です。The basic structure for code that uses a semaphore to protect resources is:


' Enter semaphore by calling one of the Wait or WaitAsync methods.  
SemaphoreSlim.Wait()  
'   
' Execute code protected by the semaphore.   
'  
SemaphoreSlim.Release()  

すべてのスレッドがセマフォを解放、ときにカウントが最大値で指定されて、セマフォが作成されたとき。When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created. セマフォのカウントは、CurrentCountプロパティ。The semaphore's count is available from the CurrentCount property.

重要

SemaphoreSlimクラスへの呼び出しでスレッドまたはタスクの id の制限はありません、 WaitWaitAsync、およびReleaseメソッド。The SemaphoreSlim class doesn't enforce thread or task identity on calls to the Wait, WaitAsync, and Release methods. さらに場合、SemaphoreSlim(Int32)コンス トラクターがインスタンス化に使用、SemaphoreSlimオブジェクト、CurrentCountコンス トラクターによって設定された値を超えるプロパティを増やすことができます。In addition, if the SemaphoreSlim(Int32) constructor is used to instantiate the SemaphoreSlim object, the CurrentCount property can increase beyond the value set by the constructor. 呼び出していることを確認するはプログラマの役目はWaitまたはWaitAsyncメソッドへの呼び出しと適切に組み合わせReleaseメソッド。It is the programmer's responsibility to ensure that calls to Wait or WaitAsync methods are appropriately paired with calls to Release methods.

コンストラクター

SemaphoreSlim(Int32) SemaphoreSlim(Int32) SemaphoreSlim(Int32) SemaphoreSlim(Int32)

同時に許可される要求の初期数を指定して、SemaphoreSlim クラスの新しいインスタンスを初期化します。Initializes a new instance of the SemaphoreSlim class, specifying the initial number of requests that can be granted concurrently.

SemaphoreSlim(Int32, Int32) SemaphoreSlim(Int32, Int32) SemaphoreSlim(Int32, Int32) SemaphoreSlim(Int32, Int32)

同時に許可される要求の初期数および最大数を指定して、SemaphoreSlim クラスの新しいインスタンスを初期化します。Initializes a new instance of the SemaphoreSlim class, specifying the initial and maximum number of requests that can be granted concurrently.

プロパティ

AvailableWaitHandle AvailableWaitHandle AvailableWaitHandle AvailableWaitHandle

セマフォの待機に使用できる WaitHandle を返します。Returns a WaitHandle that can be used to wait on the semaphore.

CurrentCount CurrentCount CurrentCount CurrentCount

SemaphoreSlim オブジェクトに入る、残りのスレッド数を取得します。Gets the number of remaining threads that can enter the SemaphoreSlim object.

メソッド

Dispose() Dispose() Dispose() Dispose()

SemaphoreSlim クラスの現在のインスタンスによって使用されているすべてのリソースを解放します。Releases all resources used by the current instance of the SemaphoreSlim class.

Dispose(Boolean) Dispose(Boolean) Dispose(Boolean) Dispose(Boolean)

SemaphoreSlim が使用しているアンマネージド リソースを解放します。オプションとして、マネージド リソースを解放することもできます。Releases the unmanaged resources used by the SemaphoreSlim, and optionally releases the managed resources.

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

指定したオブジェクトが、現在のオブジェクトと等しいかどうかを判断します。Determines whether the specified object is equal to the current object.

(Inherited from Object)
GetHashCode() GetHashCode() GetHashCode() GetHashCode()

既定のハッシュ関数として機能します。Serves as the default hash function.

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

現在のインスタンスの Type を取得します。Gets 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)
Release() Release() Release() Release()

SemaphoreSlim のオブジェクトを一度解放します。Releases the SemaphoreSlim object once.

Release(Int32) Release(Int32) Release(Int32) Release(Int32)

指定された回数だけ、SemaphoreSlim オブジェクトを解放します。Releases the SemaphoreSlim object a specified number of times.

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

現在のオブジェクトを表す文字列を返します。Returns a string that represents the current object.

(Inherited from Object)
Wait() Wait() Wait() Wait()

SemaphoreSlim に入るまで、現在のスレッドをブロックします。Blocks the current thread until it can enter the SemaphoreSlim.

Wait(CancellationToken) Wait(CancellationToken) Wait(CancellationToken) Wait(CancellationToken)

SemaphoreSlim を観察すると同時に、CancellationToken に入るまで、現在のスレッドをブロックします。Blocks the current thread until it can enter the SemaphoreSlim, while observing a CancellationToken.

Wait(Int32) Wait(Int32) Wait(Int32) Wait(Int32)

タイムアウト値を 32 ビット符号付き整数で指定して、SemaphoreSlim に入るまで、現在のスレッドをブロックします。Blocks the current thread until it can enter the SemaphoreSlim, using a 32-bit signed integer that specifies the timeout.

Wait(Int32, CancellationToken) Wait(Int32, CancellationToken) Wait(Int32, CancellationToken) Wait(Int32, CancellationToken)

SemaphoreSlim を観察すると同時に、タイムアウト値を 32 ビット符号付き整数で指定して、CancellationToken に入るまで、現在のスレッドをブロックします。Blocks the current thread until it can enter the SemaphoreSlim, using a 32-bit signed integer that specifies the timeout, while observing a CancellationToken.

Wait(TimeSpan) Wait(TimeSpan) Wait(TimeSpan) Wait(TimeSpan)

SemaphoreSlim を使用してタイムアウトを指定し、TimeSpan に入るまで、現在のスレッドをブロックします。Blocks the current thread until it can enter the SemaphoreSlim, using a TimeSpan to specify the timeout.

Wait(TimeSpan, CancellationToken) Wait(TimeSpan, CancellationToken) Wait(TimeSpan, CancellationToken) Wait(TimeSpan, CancellationToken)

SemaphoreSlim を観察すると同時に、タイムアウトを指定する TimeSpan を使用して、CancellationToken に入るまで、現在のスレッドをブロックします。Blocks the current thread until it can enter the SemaphoreSlim, using a TimeSpan that specifies the timeout, while observing a CancellationToken.

WaitAsync() WaitAsync() WaitAsync() WaitAsync()

SemaphoreSlim に移行するために非同期に待機します。Asynchronously waits to enter the SemaphoreSlim.

WaitAsync(CancellationToken) WaitAsync(CancellationToken) WaitAsync(CancellationToken) WaitAsync(CancellationToken)

SemaphoreSlim を観察する CancellationToken に移行するために非同期に待機します。Asynchronously waits to enter the SemaphoreSlim, while observing a CancellationToken.

WaitAsync(Int32) WaitAsync(Int32) WaitAsync(Int32) WaitAsync(Int32)

32 ビット符号付き整数を使用して時間間隔を測定する SemaphoreSlim に移行するために非同期に待機します。Asynchronously waits to enter the SemaphoreSlim, using a 32-bit signed integer to measure the time interval.

WaitAsync(Int32, CancellationToken) WaitAsync(Int32, CancellationToken) WaitAsync(Int32, CancellationToken) WaitAsync(Int32, CancellationToken)

32 ビット符号付き整数を使用して時間間隔を測定する一方、SemaphoreSlim を観察する CancellationToken に移行するために非同期に待機します。Asynchronously waits to enter the SemaphoreSlim, using a 32-bit signed integer to measure the time interval, while observing a CancellationToken.

WaitAsync(TimeSpan) WaitAsync(TimeSpan) WaitAsync(TimeSpan) WaitAsync(TimeSpan)

SemaphoreSlim を使用して時間間隔を測定する TimeSpan に移行するために非同期に待機します。Asynchronously waits to enter the SemaphoreSlim, using a TimeSpan to measure the time interval.

WaitAsync(TimeSpan, CancellationToken) WaitAsync(TimeSpan, CancellationToken) WaitAsync(TimeSpan, CancellationToken) WaitAsync(TimeSpan, CancellationToken)

SemaphoreSlim を使用して時間間隔を測定する一方、TimeSpan を観察する CancellationToken に移行するために非同期に待機します。Asynchronously waits to enter the SemaphoreSlim, using a TimeSpan to measure the time interval, while observing a CancellationToken.

適用対象

スレッド セーフ

すべてのパブリックおよびプロテクト メンバーSemaphoreSlimスレッド セーフでは、例外として、複数のスレッドから同時に使用できますDispose()、これを使用する必要がある場合にのみに対するその他のすべての操作、SemaphoreSlimが完了します。All public and protected members of SemaphoreSlim are thread-safe and may be used concurrently from multiple threads, with the exception of Dispose(), which must be used only when all other operations on the SemaphoreSlim have completed.

こちらもご覧ください