SemaphoreSlim 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
代表 Semaphore 的輕量型替代品,限制可同時存取一項資源或資源集區的執行緒數目。
public ref class SemaphoreSlim : IDisposable
public class SemaphoreSlim : IDisposable
[System.Runtime.InteropServices.ComVisible(false)]
public class SemaphoreSlim : IDisposable
type SemaphoreSlim = class
interface IDisposable
[<System.Runtime.InteropServices.ComVisible(false)>]
type SemaphoreSlim = class
interface IDisposable
Public Class SemaphoreSlim
Implements IDisposable
- 繼承
-
SemaphoreSlim
- 屬性
- 實作
範例
下列範例會建立最大計數為三個執行緒和零個執行緒的初始計數的號志。 此範例會啟動五個工作,全部都封鎖等候號志。 主執行緒會 Release(Int32) 呼叫 多載,將號志計數增加到其最大值,這可讓三個工作進入號志。 每次放開號志時,就會顯示先前的號志計數。 主控台訊息會追蹤號志使用。 模擬的時間間隔會針對每個執行緒稍微增加,讓輸出更容易閱讀。
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);
int semaphoreCount;
semaphore.Wait();
try
{
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);
}
finally {
semaphoreCount = semaphore.Release();
}
Console.WriteLine("Task {0} releases the semaphore; previous count: {1}.",
Task.CurrentId, semaphoreCount);
});
}
// 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.
備註
旗號有兩種類型:本機號志和具名系統號志。 本機號志是應用程式的本機旗號,系統號志會在整個作業系統中可見,而且適用于進程間同步處理。 SemaphoreSlim是類別的輕量型替代方案 Semaphore ,不會使用Windows核心旗號。 不同于 類別 Semaphore ,類別 SemaphoreSlim 不支援具名系統號志。 您只能將它當做本機號志使用。 類別 SemaphoreSlim 是單一應用程式內同步處理的建議旗號。
羽量級號志可控制應用程式本機資源的集區存取權。 當您具現化號志時,可以指定可以同時進入號志的執行緒數目上限。 您也可以指定可以同時輸入號志的初始執行緒數目。 這會定義號志的計數。
每次執行緒進入號志時都會遞減計數,並線上程釋放號志時遞增。 若要輸入號志,執行緒會呼叫其中 Wait 一個 或 WaitAsync 多載。 若要釋放號志,它會呼叫其中 Release 一個多載。 當計數達到零時,後續呼叫其中 Wait
一個方法會封鎖,直到其他執行緒釋放旗號為止。 如果封鎖多個執行緒,則不會保證順序,例如 FIFO 或 LIFO,控制執行緒何時進入號志。
使用號志來保護資源的程式碼基本結構為:
' Enter semaphore by calling one of the Wait or WaitAsync methods.
SemaphoreSlim.Wait()
'
' Execute code protected by the semaphore.
'
SemaphoreSlim.Release()
當所有線程都釋放旗號時,計數會位於建立號志時所指定的最大值。 旗號的計數可從 屬性取得 CurrentCount 。
重要
類別 SemaphoreSlim 不會對 、 WaitAsync 和 Release 方法的呼叫 Wait 強制執行執行緒或工作識別。 此外,如果使用建 SemaphoreSlim(Int32) 構函式來具現化 SemaphoreSlim 物件, CurrentCount 屬性可能會增加超過建構函式所設定的值。 程式設計人員必須負責確保呼叫 Wait 或 WaitAsync 方法與方法的呼叫 Release 適當配對。
建構函式
SemaphoreSlim(Int32) |
指定可同時授與的初始要求數目,初始化 SemaphoreSlim 類別的新執行個體。 |
SemaphoreSlim(Int32, Int32) |
指定可同時授與的初始要求數目及最大數目,初始化 SemaphoreSlim 類別的新執行個體。 |
屬性
AvailableWaitHandle |
傳回可用來等候號誌的 WaitHandle。 |
CurrentCount |
取得可以進入 SemaphoreSlim 物件的剩餘執行緒數目。 |
方法
適用於
執行緒安全性
的所有公用和受保護成員 SemaphoreSlim 都是安全線程,而且可以從多個執行緒同時使用,但例外狀況是 ,只有在 Dispose() 上所有其他作業 SemaphoreSlim 都已完成時,才必須使用。