SemaphoreSlimクラス

リソースまたはリソースのプールに同時にアクセスできるスレッドの数を制限できます。これはSemaphoreクラスの軽量な代替です。

コンストラクタ

public SemaphoreSlim (
    int initialCount,
    int maxCount
    );
SemaphoreSlim(Int32, Int32) - SemaphoreSlim コンストラクター (System.Threading) | Microsoft Learn

maxCountを省略するとInt32.MaxValueに設定されます。SemaphoreSlim - SemaphoreSlim.cs

initialCountがCurrentCountプロパティの初期値となります。そしてRelease()でSemaphoreSlimを解放したときに、maxCountを超えるとSemaphoreFullExceptionが投げられます。

SemaphoreSlim semaphore = new SemaphoreSlim(1, 3);
int c1 = semaphore.Release(1); // 1
int c2 = semaphore.Release(1); // 2

semaphore.Release(); // SemaphoreFullException「指定されたカウントをセマフォに追加すると、カウントの最大値を超えます。」

要求の最大数を1として、Wait()と同一のスレッドでRelease()を呼ぶならば、lockMonitorでも代用可能です。

プロパティ

プロパティ 内容
int CurrentCount SemaphoreSlimオブジェクトに入ることができる、残りのスレッド数
WaitHandle AvailableWaitHandle セマフォの待機に使用できるWaitHandle

CurrentCount

SemaphoreSlimに入ることができるスレッド数で、Wait()で入ると減少し、Release()で解放すると増加します。

SemaphoreSlim semaphore = new SemaphoreSlim(3); // 初期値はコンストラクタで指定する
int c1 = semaphore.CurrentCount; // 3

semaphore.Wait();                // 減算される
int c2 = semaphore.CurrentCount; // 2

semaphore.Release();             // 加算される
int c3 = semaphore.CurrentCount; // 3

メソッド

Wait()

CurrentCountが1以上となり、SemaphoreSlimに入れるまで現在のスレッドはブロックされます。この待ちをタイムアウトさせるにはWait(Int32)を、非同期に待たせるにはWaitAsync()を呼びます。

タイムアウトを指定しないWait()は、Wait(Timeout.Infinite)とするのと同じです。Wait - SemaphoreSlim.cs

public void Wait ();

SemaphoreSlimに入れたときはCurrentCountが1減算されます。

SemaphoreSlim semaphore = new SemaphoreSlim(1);

semaphore.Wait();
try
{
    // クリティカル セクション
}
finally
{
    semaphore.Release();
}

Wait(Int32)

SemaphoreSlimに入れないときにスレッドをブロックせず、即座に結果を返すようにするにはタイムアウトを0とします。

SemaphoreSlim semaphore = new SemaphoreSlim(1);

if (semaphore.Wait(0))
{
    try
    {
    }
    finally
    {
        semaphore.Release();
    }
}
else { } // SemaphoreSlimに入れなかった

WaitAsync()

SemaphoreSlimに入れるまで非同期に待たせられます。

public System.Threading.Tasks.Task WaitAsync ();

返されるTaskは、SemaphoreSlimに入ったときに完了します。

Release()

SemaphoreSlimを1つ解放できます。

public int Release ();

CurrentCountが1加算され、加算前の値が返されます。

AsyncLockクラス

SemaphoreSlimクラスを簡潔に記述できるようにしたクラスです。

Microsoft Learnから検索