Semaphore 建構函式

定義

初始化 Semaphore 類別的新執行個體。

多載

名稱 Description
Semaphore(Int32, Int32)

初始化該類別的新實例 Semaphore ,指定初始條目數及最大並行條目數。

Semaphore(Int32, Int32, String)

初始化該類別的新實例 Semaphore ,指定初始條目數與最大並行條目數,並可選擇指定系統信號量物件的名稱。

Semaphore(Int32, Int32, String, Boolean)

初始化該類別的新實例 Semaphore ,指定初始條目數及最大並行條目數,並可選擇指定系統信號量物件名稱,並指定一個變數接收值,表示是否建立了新的系統信號量。

Semaphore(Int32, Int32, String, NamedWaitHandleOptions)

初始化類別的新實例 Semaphore ,指定初始條目數及最大同時條目數,並可選擇性地指定系統信號量物件名稱及設定使用者範圍與會話範圍存取的選項。

Semaphore(Int32, Int32, String, Boolean, SemaphoreSecurity)

初始化該類別的新實例 Semaphore ,指定初始條目數及最大並行條目數,可選擇性地指定系統信號量物件名稱,指定一個變數接收是否建立新系統信號量的值,並指定該系統信號量的安全存取控制。

Semaphore(Int32, Int32, String, NamedWaitHandleOptions, Boolean)

初始化該類別的新實例 Semaphore ,指定初始條目數及最大並行條目數,可選擇性地指定系統信號量物件名稱及設定使用者範圍與會話範圍存取的選項,並指定一個變數接收值,表示是否建立了新的系統信號量。

Semaphore(Int32, Int32)

來源:
Semaphore.cs
來源:
Semaphore.cs
來源:
Semaphore.cs
來源:
Semaphore.cs
來源:
Semaphore.cs

初始化該類別的新實例 Semaphore ,指定初始條目數及最大並行條目數。

public:
 Semaphore(int initialCount, int maximumCount);
public Semaphore(int initialCount, int maximumCount);
new System.Threading.Semaphore : int * int -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer)

參數

initialCount
Int32

可同時核對信號量的初始請求數量。

maximumCount
Int32

同時可授予的臂量請求數。

例外狀況

initialCount 大於 maximumCount

maximumCount 小於1。

-或-

initialCount 小於0。

範例

以下範例產生一個最大計數為三、初始計數為零的信號量。 範例中起始五個執行緒,這些執行緒會阻塞等待信號板的出現。 主執行緒利用 Release(Int32) 方法超載將信號量數量提高到最大,允許三個執行緒進入信號量。 每個執行緒會使用該 Thread.Sleep 方法等待一秒,模擬工作,然後呼叫 Release() 方法過載以釋放信號量。 每次釋放臂板時,都會顯示前一次的臂板計數。 主控台訊息會追蹤臂板的使用。 模擬工作間隔會對每個線程略有增加,以使輸出更易閱讀。

using System;
using System.Threading;

public class Example
{
    // A semaphore that simulates a limited resource pool.
    //
    private static Semaphore _pool;

    // A padding interval to make the output more orderly.
    private static int _padding;

    public static void Main()
    {
        // Create a semaphore that can satisfy up to three
        // concurrent requests. Use an initial count of zero,
        // so that the entire semaphore count is initially
        // owned by the main program thread.
        //
        _pool = new Semaphore(initialCount: 0, maximumCount: 3);

        // Create and start five numbered threads. 
        //
        for(int i = 1; i <= 5; i++)
        {
            Thread t = new Thread(new ParameterizedThreadStart(Worker));

            // Start the thread, passing the number.
            //
            t.Start(i);
        }

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

        // The main thread starts out holding the entire
        // semaphore count. Calling Release(3) brings the 
        // semaphore count back to its maximum value, and
        // allows the waiting threads to enter the semaphore,
        // up to three at a time.
        //
        Console.WriteLine("Main thread calls Release(3).");
        _pool.Release(releaseCount: 3);

        Console.WriteLine("Main thread exits.");
    }

    private static void Worker(object num)
    {
        // Each worker thread begins by requesting the
        // semaphore.
        Console.WriteLine("Thread {0} begins " +
            "and waits for the semaphore.", num);
        _pool.WaitOne();

        // A padding interval to make the output more orderly.
        int padding = Interlocked.Add(ref _padding, 100);

        Console.WriteLine("Thread {0} enters the semaphore.", num);
        
        // The thread's "work" consists of sleeping for 
        // about a second. Each thread "works" a little 
        // longer, just to make the output more orderly.
        //
        Thread.Sleep(1000 + padding);

        Console.WriteLine("Thread {0} releases the semaphore.", num);
        Console.WriteLine("Thread {0} previous semaphore count: {1}",
            num, _pool.Release());
    }
}
Imports System.Threading

Public Class Example

    ' A semaphore that simulates a limited resource pool.
    '
    Private Shared _pool As Semaphore

    ' A padding interval to make the output more orderly.
    Private Shared _padding As Integer

    <MTAThread> _
    Public Shared Sub Main()
        ' Create a semaphore that can satisfy up to three
        ' concurrent requests. Use an initial count of zero,
        ' so that the entire semaphore count is initially
        ' owned by the main program thread.
        '
        _pool = New Semaphore(0, 3)

        ' Create and start five numbered threads. 
        '
        For i As Integer = 1 To 5
            Dim t As New Thread(New ParameterizedThreadStart(AddressOf Worker))
            'Dim t As New Thread(AddressOf Worker)

            ' Start the thread, passing the number.
            '
            t.Start(i)
        Next i

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

        ' The main thread starts out holding the entire
        ' semaphore count. Calling Release(3) brings the 
        ' semaphore count back to its maximum value, and
        ' allows the waiting threads to enter the semaphore,
        ' up to three at a time.
        '
        Console.WriteLine("Main thread calls Release(3).")
        _pool.Release(3)

        Console.WriteLine("Main thread exits.")
    End Sub

    Private Shared Sub Worker(ByVal num As Object)
        ' Each worker thread begins by requesting the
        ' semaphore.
        Console.WriteLine("Thread {0} begins " _
            & "and waits for the semaphore.", num)
        _pool.WaitOne()

        ' A padding interval to make the output more orderly.
        Dim padding As Integer = Interlocked.Add(_padding, 100)

        Console.WriteLine("Thread {0} enters the semaphore.", num)
        
        ' The thread's "work" consists of sleeping for 
        ' about a second. Each thread "works" a little 
        ' longer, just to make the output more orderly.
        '
        Thread.Sleep(1000 + padding)

        Console.WriteLine("Thread {0} releases the semaphore.", num)
        Console.WriteLine("Thread {0} previous semaphore count: {1}", _
            num, _
            _pool.Release())
    End Sub
End Class

備註

此建構子初始化一個未命名的信號量。 所有使用此類信號量實例的執行緒必須包含該實例的參考。

initialCount 小於 maximumCount,效果與當前執行緒呼叫WaitOnemaximumCount 次數(減initialCount去)相同。 如果你不想為產生信號量的執行緒保留任何條目,請對 和 maximumCount使用 相同的數字。initialCount

另請參閱

適用於

Semaphore(Int32, Int32, String)

來源:
Semaphore.cs
來源:
Semaphore.cs
來源:
Semaphore.cs
來源:
Semaphore.cs
來源:
Semaphore.cs

初始化該類別的新實例 Semaphore ,指定初始條目數與最大並行條目數,並可選擇指定系統信號量物件的名稱。

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name);
public Semaphore(int initialCount, int maximumCount, string name);
public Semaphore(int initialCount, int maximumCount, string? name);
new System.Threading.Semaphore : int * int * string -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String)

參數

initialCount
Int32

可同時核對信號量的初始請求數量。

maximumCount
Int32

同時可授予的臂量請求數。

name
String

若同步物件要與其他程序共享,則使用名稱;否則, null 或空字串。 名稱會區分大小寫。 反斜線字元(\)是保留的,只能用來指定命名空間。 欲了解更多命名空間資訊,請參閱備註區。 根據作業系統不同,名稱可能有進一步限制。 例如,在基於 Unix 的作業系統中,排除命名空間後的名稱必須是有效的檔名。

例外狀況

initialCount 大於 maximumCount

-或-

僅限 Framework .NET:name 超過 MAX_PATH(260 個字元)。

maximumCount 小於1。

-或-

initialCount 小於0。

name 無效。 這可能有各種原因,包括作業系統可能施加的一些限制,例如未知的前綴或無效字元。 請注意,名稱及常見前綴「Global\」與「Local\」皆為大小寫區分。

-或-

還有其他錯誤。 房產 HResult 可能會提供更多資訊。

Windows 僅有:name 指定了一個未知命名空間。 更多資訊請參閱 物件名稱

name太長了。 長度限制可能依作業系統或設定而異。

命名的信號量存在且具備存取控制安全性,而使用者則沒有 FullControl

無法建立與所提供的 name 同步物件。 不同類型的同步物件可能名稱相同。

範例

以下程式碼範例展示了命名信號量的跨程序行為。 範例中會產生一個命名的臂板,最大計數為五,初始計數為五。 程式會呼叫三次方法 WaitOne 。 因此,如果你從兩個指令視窗執行編譯後的範例,第二個副本會在第三次呼叫時 WaitOne阻塞。 釋放程式第一個副本中的一個或多個條目以解除第二個封堵。

using System;
using System.Threading;

public class Example
{
    public static void Main()
    {
        // Create a Semaphore object that represents the named 
        // system semaphore "SemaphoreExample3". The semaphore has a
        // maximum count of five. The initial count is also five. 
        // There is no point in using a smaller initial count,
        // because the initial count is not used if this program
        // doesn't create the named system semaphore, and with 
        // this method overload there is no way to tell. Thus, this
        // program assumes that it is competing with other
        // programs for the semaphore.
        //
        Semaphore sem = new Semaphore(5, 5, "SemaphoreExample3");

        // Attempt to enter the semaphore three times. If another 
        // copy of this program is already running, only the first
        // two requests can be satisfied. The third blocks. Note 
        // that in a real application, timeouts should be used
        // on the WaitOne calls, to avoid deadlocks.
        //
        sem.WaitOne();
        Console.WriteLine("Entered the semaphore once.");
        sem.WaitOne();
        Console.WriteLine("Entered the semaphore twice.");
        sem.WaitOne();
        Console.WriteLine("Entered the semaphore three times.");

        // The thread executing this program has entered the 
        // semaphore three times. If a second copy of the program
        // is run, it will block until this program releases the 
        // semaphore at least once.
        //
        Console.WriteLine("Enter the number of times to call Release.");
        int n;
        if (int.TryParse(Console.ReadLine(), out n))
        {
            sem.Release(n);
        }

        int remaining = 3 - n;
        if (remaining > 0)
        {
            Console.WriteLine("Press Enter to release the remaining " +
                "count ({0}) and exit the program.", remaining);
            Console.ReadLine();
            sem.Release(remaining);
        }
    }
}
Imports System.Threading

Public Class Example

    <MTAThread> _
    Public Shared Sub Main()
        ' Create a Semaphore object that represents the named 
        ' system semaphore "SemaphoreExample3". The semaphore has a
        ' maximum count of five. The initial count is also five. 
        ' There is no point in using a smaller initial count,
        ' because the initial count is not used if this program
        ' doesn't create the named system semaphore, and with 
        ' this method overload there is no way to tell. Thus, this
        ' program assumes that it is competing with other
        ' programs for the semaphore.
        '
        Dim sem As New Semaphore(5, 5, "SemaphoreExample3")

        ' Attempt to enter the semaphore three times. If another 
        ' copy of this program is already running, only the first
        ' two requests can be satisfied. The third blocks. Note 
        ' that in a real application, timeouts should be used
        ' on the WaitOne calls, to avoid deadlocks.
        '
        sem.WaitOne()
        Console.WriteLine("Entered the semaphore once.")
        sem.WaitOne()
        Console.WriteLine("Entered the semaphore twice.")
        sem.WaitOne()
        Console.WriteLine("Entered the semaphore three times.")

        ' The thread executing this program has entered the 
        ' semaphore three times. If a second copy of the program
        ' is run, it will block until this program releases the 
        ' semaphore at least once.
        '
        Console.WriteLine("Enter the number of times to call Release.")
        Dim n As Integer
        If Integer.TryParse(Console.ReadLine(), n) Then
            sem.Release(n)
        End If

        Dim remaining As Integer = 3 - n
        If (remaining) > 0 Then
            Console.WriteLine("Press Enter to release the remaining " _
                & "count ({0}) and exit the program.", remaining)
            Console.ReadLine()
            sem.Release(remaining)
        End If

    End Sub 
End Class

備註

此建構器初始化一個 Semaphore 代表命名系統信號量的物件。 你可以建立多個 Semaphore 物件,代表同一個命名的系統信號量。

可以name以 或 Global\ 作為前綴Local\,以指定命名空間。 當 Global 命名空間被指定時,同步物件可以與系統上的任何程序共享。 當 Local 指定命名空間時(這也是未指定命名空間時的預設),同步物件可能會與同一會話中的程序共享。 在 Windows 上,會話是登入會話,服務通常在不同的非互動會話中執行。 在類 Unix 作業系統中,每個 shell 都有自己的會話。 會話本地同步物件可能適合在具有父/子關係且所有程序都在同一會話中執行的程序間同步。 欲了解更多關於Windows同步物件名稱的資訊,請參見 Object Names

如果已提供 a name ,且命名空間中已有該請求類型的同步物件,則會使用現有的同步物件。 如果命名空間中已有不同類型的同步物件,則會拋出 a WaitHandleCannotBeOpenedException 。 否則,會建立一個新的同步物件。

若系統中不存在命名的信號量,則以初始數量及最大數量為 initialCountmaximumCount和 來建立。 若已命名系統的信號量存在且 initialCountmaximumCount 未被使用,即使值無效仍會產生例外。 如果你需要判斷是否有命名系統的信號量被創建,建議使用 Semaphore(Int32, Int32, String, Boolean) 建構器過載。

Important

使用此建構子超載時,建議的做法是將 和 initialCount指定相同的數量。maximumCountinitialCountmaximumCount於 ,且建立命名系統信號量,效果與當前執行緒呼叫WaitOnemaximumCount次數(減initialCount去)相同。 然而,在這種建構器過載下,無法判斷是否建立了命名系統的信號量。

如果你指定 null 或 一個空字串 , name會產生一個局部的信號量,就像你呼叫 Semaphore(Int32, Int32) 了建構子過載一樣。

由於命名的信號量在整個作業系統中可見,因此可用來協調跨流程邊界的資源使用。

如果你想知道是否存在命名系統的信號量,請使用這個 OpenExisting 方法。 該 OpenExisting 方法嘗試開啟一個已存在的命名信號量,若系統信號量不存在則拋出例外。

Caution

預設情況下,命名的信號量不限於創建它的使用者。 其他使用者可能能夠開啟並使用信號旗,包括多次取得信號旗卻不釋放來干擾信號量。 為了限制特定使用者的存取,你可以使用建構器超載,或 SemaphoreAcl 在建立命名旗號時傳遞 a SemaphoreSecurity 。 避免在可能有不受信任使用者執行程式碼的系統中使用無存取限制的命名信號量。

另請參閱

適用於

Semaphore(Int32, Int32, String, Boolean)

來源:
Semaphore.cs
來源:
Semaphore.cs
來源:
Semaphore.cs
來源:
Semaphore.cs
來源:
Semaphore.cs

初始化該類別的新實例 Semaphore ,指定初始條目數及最大並行條目數,並可選擇指定系統信號量物件名稱,並指定一個變數接收值,表示是否建立了新的系統信號量。

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name, [Runtime::InteropServices::Out] bool % createdNew);
public Semaphore(int initialCount, int maximumCount, string name, out bool createdNew);
public Semaphore(int initialCount, int maximumCount, string? name, out bool createdNew);
new System.Threading.Semaphore : int * int * string * bool -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String, ByRef createdNew As Boolean)

參數

initialCount
Int32

可同時滿足的旗量初始請求數量。

maximumCount
Int32

同時可滿足的最大信號量請求數。

name
String

若同步物件要與其他程序共享,則使用名稱;否則, null 或空字串。 名稱會區分大小寫。 反斜線字元(\)是保留的,只能用來指定命名空間。 欲了解更多命名空間資訊,請參閱備註區。 根據作業系統不同,名稱可能有進一步限制。 例如,在基於 Unix 的作業系統中,排除命名空間後的名稱必須是有效的檔名。

createdNew
Boolean

當此方法回傳時,包含 true 是否已建立本地信號量(即 namenull 空字串),或是否已建立指定的命名系統信號量; false 若該指定系統信號量已存在。 這個參數會未初始化傳遞。

例外狀況

initialCount 大於 maximumCount

-或-

僅限 Framework .NET:name 超過 MAX_PATH(260 個字元)。

maximumCount 小於1。

-或-

initialCount 小於0。

name 無效。 這可能有各種原因,包括作業系統可能施加的一些限制,例如未知的前綴或無效字元。 請注意,名稱及常見前綴「Global\」與「Local\」皆為大小寫區分。

-或-

還有其他錯誤。 房產 HResult 可能會提供更多資訊。

Windows 僅有:name 指定了一個未知命名空間。 更多資訊請參閱 物件名稱

name太長了。 長度限制可能依作業系統或設定而異。

命名的信號量存在且具備存取控制安全性,而使用者則沒有 FullControl

無法建立與所提供的 name 同步物件。 不同類型的同步物件可能名稱相同。

範例

以下程式碼範例展示了命名信號量的跨程序行為。 此範例會產生一個命名的臂板,最大數量為五,初始數量為二。 也就是說,它為呼叫建構子的執行緒保留三個項目。 若 createNewfalse程式會呼叫該方法三 WaitOne 次。 因此,如果你從兩個指令視窗執行編譯後的範例,第二個副本會在第三次呼叫時 WaitOne阻塞。 釋放程式第一個副本中的一個或多個條目以解除第二個封堵。

using System;
using System.Threading;

public class Example
{
    public static void Main()
    {
        // The value of this variable is set by the semaphore
        // constructor. It is true if the named system semaphore was
        // created, and false if the named semaphore already existed.
        //
        bool semaphoreWasCreated;

        // Create a Semaphore object that represents the named 
        // system semaphore "SemaphoreExample". The semaphore has a
        // maximum count of five, and an initial count of two. The
        // Boolean value that indicates creation of the underlying 
        // system object is placed in semaphoreWasCreated.
        //
        Semaphore sem = new Semaphore(2, 5, "SemaphoreExample", 
            out semaphoreWasCreated);

        if (semaphoreWasCreated)
        {
            // If the named system semaphore was created, its count is
            // set to the initial count requested in the constructor.
            // In effect, the current thread has entered the semaphore
            // three times.
            // 
            Console.WriteLine("Entered the semaphore three times.");
        }
        else
        {      
            // If the named system semaphore was not created,  
            // attempt to enter it three times. If another copy of
            // this program is already running, only the first two
            // requests can be satisfied. The third blocks.
            //
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore once.");
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore twice.");
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore three times.");
        }

        // The thread executing this program has entered the 
        // semaphore three times. If a second copy of the program
        // is run, it will block until this program releases the 
        // semaphore at least once.
        //
        Console.WriteLine("Enter the number of times to call Release.");
        int n;
        if (int.TryParse(Console.ReadLine(), out n))
        {
            sem.Release(n);
        }

        int remaining = 3 - n;
        if (remaining > 0)
        {
            Console.WriteLine("Press Enter to release the remaining " +
                "count ({0}) and exit the program.", remaining);
            Console.ReadLine();
            sem.Release(remaining);
        }
    } 
}
Imports System.Threading

Public Class Example

    <MTAThread> _
    Public Shared Sub Main()
        ' The value of this variable is set by the semaphore
        ' constructor. It is True if the named system semaphore was
        ' created, and False if the named semaphore already existed.
        '
        Dim semaphoreWasCreated As Boolean

        ' Create a Semaphore object that represents the named 
        ' system semaphore "SemaphoreExample". The semaphore has a
        ' maximum count of five, and an initial count of two. The
        ' Boolean value that indicates creation of the underlying 
        ' system object is placed in semaphoreWasCreated.
        '
        Dim sem As New Semaphore(2, 5, "SemaphoreExample", _
            semaphoreWasCreated)

        If semaphoreWasCreated Then
            ' If the named system semaphore was created, its count is
            ' set to the initial count requested in the constructor.
            ' In effect, the current thread has entered the semaphore
            ' three times.
            ' 
            Console.WriteLine("Entered the semaphore three times.")
        Else
            ' If the named system semaphore was not created,  
            ' attempt to enter it three times. If another copy of
            ' this program is already running, only the first two
            ' requests can be satisfied. The third blocks.
            '
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore once.")
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore twice.")
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore three times.")
        End If

        ' The thread executing this program has entered the 
        ' semaphore three times. If a second copy of the program
        ' is run, it will block until this program releases the 
        ' semaphore at least once.
        '
        Console.WriteLine("Enter the number of times to call Release.")
        Dim n As Integer
        If Integer.TryParse(Console.ReadLine(), n) Then
            sem.Release(n)
        End If

        Dim remaining As Integer = 3 - n
        If (remaining) > 0 Then
            Console.WriteLine("Press Enter to release the remaining " _
                & "count ({0}) and exit the program.", remaining)
            Console.ReadLine()
            sem.Release(remaining)
        End If

    End Sub 
End Class

備註

可以name以 或 Global\ 作為前綴Local\,以指定命名空間。 當 Global 命名空間被指定時,同步物件可以與系統上的任何程序共享。 當 Local 指定命名空間時(這也是未指定命名空間時的預設),同步物件可能會與同一會話中的程序共享。 在 Windows 上,會話是登入會話,服務通常在不同的非互動會話中執行。 在類 Unix 作業系統中,每個 shell 都有自己的會話。 會話本地同步物件可能適合在具有父/子關係且所有程序都在同一會話中執行的程序間同步。 欲了解更多關於Windows同步物件名稱的資訊,請參見 Object Names

如果已提供 a name ,且命名空間中已有該請求類型的同步物件,則會使用現有的同步物件。 如果命名空間中已有不同類型的同步物件,則會拋出 a WaitHandleCannotBeOpenedException 。 否則,會建立一個新的同步物件。

此建構器初始化一個 Semaphore 代表命名系統信號量的物件。 你可以建立多個 Semaphore 物件,代表同一個命名的系統信號量。

若系統中不存在命名的信號量,則以初始數量及最大數量為 initialCountmaximumCount和 來建立。 若已命名系統的信號量存在且 initialCountmaximumCount 未被使用,即使值無效仍會產生例外。 用來 createdNew 判斷系統的信號量是否被建立。

initialCountmaximumCount於 ,且 createdNewtrue,效果與當前執行緒呼叫WaitOnemaximumCount次數(減initialCount去)相同。

如果你指定 null 或 一個空字串 , name會產生一個局部的信號量,就像你呼叫 Semaphore(Int32, Int32) 了建構子過載一樣。 在此情況下, createdNew 總是 true

由於命名的信號量在整個作業系統中可見,因此可用來協調跨流程邊界的資源使用。

Caution

預設情況下,命名的信號量不限於創建它的使用者。 其他使用者可能能夠開啟並使用信號旗,包括多次取得信號旗卻不釋放來干擾信號量。 為了限制特定使用者的存取,你可以使用建構器超載,或 SemaphoreAcl 在建立命名旗號時傳遞 a SemaphoreSecurity 。 避免在可能有不受信任使用者執行程式碼的系統中使用無存取限制的命名信號量。

另請參閱

適用於

Semaphore(Int32, Int32, String, NamedWaitHandleOptions)

來源:
Semaphore.cs
來源:
Semaphore.cs

初始化類別的新實例 Semaphore ,指定初始條目數及最大同時條目數,並可選擇性地指定系統信號量物件名稱及設定使用者範圍與會話範圍存取的選項。

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name, System::Threading::NamedWaitHandleOptions options);
public Semaphore(int initialCount, int maximumCount, string? name, System.Threading.NamedWaitHandleOptions options);
new System.Threading.Semaphore : int * int * string * System.Threading.NamedWaitHandleOptions -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String, options As NamedWaitHandleOptions)

參數

initialCount
Int32

可同時滿足的旗量初始請求數量。

maximumCount
Int32

同時可滿足的最大信號量請求數。

name
String

若同步物件要與其他程序共享,則使用名稱;否則, null 或空字串。 名稱會區分大小寫。

options
NamedWaitHandleOptions

命名信號板的範圍選項。 預設權限僅限於目前使用者和當前會話。 指定的選項可能會影響名稱的命名空間以及對底層信號量物件的存取。

例外狀況

initialCount 大於 maximumCount

-或-

initialCount 小於0。

name 無效。 這可能有各種原因,包括作業系統可能施加的一些限制,例如未知的前綴或無效字元。 請注意,名稱及常見前綴「Global\」與「Local\」皆為大小寫區分。

-或-

還有其他錯誤。 房產 HResult 可能會提供更多資訊。

Windows 僅有:name 指定了一個未知命名空間。 更多資訊請參閱 物件名稱

name太長了。 長度限制可能依作業系統或設定而異。

命名的信號量存在且具備存取控制安全性,而使用者則沒有 FullControl

無法建立與所提供的 name 同步物件。 不同類型的同步物件可能名稱相同。

-或-

存在具有指定 name 條件的物件,但指定的 options 物件與現有物件的選項不相容。

備註

此建構器初始化一個 Semaphore 代表命名系統信號量的物件。 你可以建立多個 Semaphore 物件,代表同一個命名的系統信號量。

若已提供 a name ,且命名空間中已有該類型的同步物件,則使用現有的同步物件,除非 options 指定存取權限僅限當前使用者且同步物件與其不相容,此時會拋出 a WaitHandleCannotBeOpenedException 。 如果命名空間中已經存在不同類型的同步物件,也會拋出 a WaitHandleCannotBeOpenedException 。 否則,會建立一個新的同步物件。

若系統中不存在命名的信號量,則以初始數量及最大數量為 initialCountmaximumCount和 來建立。 若已命名系統的信號量存在且 initialCountmaximumCount 未被使用,即使值無效仍會產生例外。 如果你需要判斷是否有命名系統的信號量被創建,建議使用 Semaphore(Int32, Int32, String, Boolean) 建構器過載。

Important

使用此建構子超載時,建議的做法是將 和 initialCount指定相同的數量。maximumCountinitialCountmaximumCount於 ,且建立命名系統信號量,效果與當前執行緒呼叫WaitOnemaximumCount次數(減initialCount去)相同。 然而,在這種構造器過載的情況下,無法判斷是否建立了命名系統的信號量。

如果你指定 null 或 一個空字串 , name會產生一個局部的信號量,就像你呼叫 Semaphore(Int32, Int32) 了建構子過載一樣。

由於命名的信號量在整個作業系統中可見,因此可用來協調跨流程邊界的資源使用。

如果你想知道是否存在命名系統的信號量,請使用這個 OpenExisting 方法。 該 OpenExisting 方法嘗試開啟一個已存在的命名信號量,若系統信號量不存在則拋出例外。

在Windows上,可以提供options來指定該命名的信號量是僅對當前使用者開放,還是所有使用者都能存取。 它也允許你指定命名的信號量是只對當前會話中的程序可存取,還是所有會話都能存取。 如需詳細資訊,請參閱NamedWaitHandleOptions

Caution

在基於 Unix 的作業系統中,該 options 參數不影響,因為不支援命名的信號量。

另請參閱

適用於

Semaphore(Int32, Int32, String, Boolean, SemaphoreSecurity)

初始化該類別的新實例 Semaphore ,指定初始條目數及最大並行條目數,可選擇性地指定系統信號量物件名稱,指定一個變數接收是否建立新系統信號量的值,並指定該系統信號量的安全存取控制。

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name, [Runtime::InteropServices::Out] bool % createdNew, System::Security::AccessControl::SemaphoreSecurity ^ semaphoreSecurity);
public Semaphore(int initialCount, int maximumCount, string name, out bool createdNew, System.Security.AccessControl.SemaphoreSecurity semaphoreSecurity);
new System.Threading.Semaphore : int * int * string * bool * System.Security.AccessControl.SemaphoreSecurity -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String, ByRef createdNew As Boolean, semaphoreSecurity As SemaphoreSecurity)

參數

initialCount
Int32

可同時滿足的旗量初始請求數量。

maximumCount
Int32

同時可滿足的最大信號量請求數。

name
String

若同步物件要與其他程序共享,則使用名稱;否則, null 或空字串。 名稱會區分大小寫。 反斜線字元(\)是保留的,只能用來指定命名空間。 欲了解更多命名空間資訊,請參閱備註區。 根據作業系統不同,名稱可能有進一步限制。 例如,在基於 Unix 的作業系統中,排除命名空間後的名稱必須是有效的檔名。

createdNew
Boolean

當此方法回傳時,包含 true 是否已建立本地信號量(即 namenull 空字串),或是否已建立指定的命名系統信號量; false 若該指定系統信號量已存在。 這個參數會未初始化傳遞。

semaphoreSecurity
SemaphoreSecurity

一個 SemaphoreSecurity 代表要套用於命名系統信號量的存取控制安全性的物件。

例外狀況

initialCount 大於 maximumCount

-或-

僅限 Framework .NET:name 超過 MAX_PATH(260 個字元)。

maximumCount 小於1。

-或-

initialCount 小於0。

命名的信號量存在且具備存取控制安全性,而使用者則沒有 FullControl

name 無效。 這可能有各種原因,包括作業系統可能施加的一些限制,例如未知的前綴或無效字元。 請注意,名稱及常見前綴「Global\」與「Local\」皆為大小寫區分。

-或-

還有其他錯誤。 房產 HResult 可能會提供更多資訊。

Windows 僅有:name 指定了一個未知命名空間。 更多資訊請參閱 物件名稱

name太長了。 長度限制可能依作業系統或設定而異。

無法建立與所提供的 name 同步物件。 不同類型的同步物件可能名稱相同。

範例

以下程式碼範例展示了具存取控制安全性的命名信號量的跨程序行為。 範例使用 OpenExisting(String) 方法過載來測試是否存在命名的信號量。 若不存在該信號量,則最多可建立兩個,並設有存取控制安全機制,禁止現有使用者使用信號量,但允許讀取及更改信號量的權限。 如果你從兩個指令視窗執行編譯後的範例,第二個副本會在呼叫該 OpenExisting(String) 方法時拋出存取違規例外。 例外被捕捉,範例利用 OpenExisting(String, SemaphoreRights) 方法超載開啟帶有讀取與變更權限的信號量。

權限變更後,信號量會被開啟,並取得進入與釋放所需的權限。 如果你從第三個指令視窗執行編譯後的範例,它會使用新的權限執行。

using System;
using System.Threading;
using System.Security.AccessControl;

internal class Example
{
    internal static void Main()
    {
        const string semaphoreName = "SemaphoreExample5";

        Semaphore sem = null;
        bool doesNotExist = false;
        bool unauthorized = false;

        // Attempt to open the named semaphore.
        try
        {
            // Open the semaphore with (SemaphoreRights.Synchronize
            // | SemaphoreRights.Modify), to enter and release the
            // named semaphore.
            //
            sem = Semaphore.OpenExisting(semaphoreName);
        }
        catch(WaitHandleCannotBeOpenedException)
        {
            Console.WriteLine("Semaphore does not exist.");
            doesNotExist = true;
        }
        catch(UnauthorizedAccessException ex)
        {
            Console.WriteLine("Unauthorized access: {0}", ex.Message);
            unauthorized = true;
        }

        // There are three cases: (1) The semaphore does not exist.
        // (2) The semaphore exists, but the current user doesn't 
        // have access. (3) The semaphore exists and the user has
        // access.
        //
        if (doesNotExist)
        {
            // The semaphore does not exist, so create it.
            //
            // The value of this variable is set by the semaphore
            // constructor. It is true if the named system semaphore was
            // created, and false if the named semaphore already existed.
            //
            bool semaphoreWasCreated;

            // Create an access control list (ACL) that denies the
            // current user the right to enter or release the 
            // semaphore, but allows the right to read and change
            // security information for the semaphore.
            //
            string user = Environment.UserDomainName + "\\" 
                + Environment.UserName;
            SemaphoreSecurity semSec = new SemaphoreSecurity();

            SemaphoreAccessRule rule = new SemaphoreAccessRule(
                user, 
                SemaphoreRights.Synchronize | SemaphoreRights.Modify, 
                AccessControlType.Deny);
            semSec.AddAccessRule(rule);

            rule = new SemaphoreAccessRule(
                user, 
                SemaphoreRights.ReadPermissions | SemaphoreRights.ChangePermissions,
                AccessControlType.Allow);
            semSec.AddAccessRule(rule);

            // Create a Semaphore object that represents the system
            // semaphore named by the constant 'semaphoreName', with
            // maximum count three, initial count three, and the
            // specified security access. The Boolean value that 
            // indicates creation of the underlying system object is
            // placed in semaphoreWasCreated.
            //
            sem = new Semaphore(3, 3, semaphoreName, 
                out semaphoreWasCreated, semSec);

            // If the named system semaphore was created, it can be
            // used by the current instance of this program, even 
            // though the current user is denied access. The current
            // program enters the semaphore. Otherwise, exit the
            // program.
            // 
            if (semaphoreWasCreated)
            {
                Console.WriteLine("Created the semaphore.");
            }
            else
            {
                Console.WriteLine("Unable to create the semaphore.");
                return;
            }
        }
        else if (unauthorized)
        {
            // Open the semaphore to read and change the access
            // control security. The access control security defined
            // above allows the current user to do this.
            //
            try
            {
                sem = Semaphore.OpenExisting(
                    semaphoreName, 
                    SemaphoreRights.ReadPermissions 
                        | SemaphoreRights.ChangePermissions);

                // Get the current ACL. This requires 
                // SemaphoreRights.ReadPermissions.
                SemaphoreSecurity semSec = sem.GetAccessControl();
                
                string user = Environment.UserDomainName + "\\" 
                    + Environment.UserName;

                // First, the rule that denied the current user 
                // the right to enter and release the semaphore must
                // be removed.
                SemaphoreAccessRule rule = new SemaphoreAccessRule(
                    user, 
                    SemaphoreRights.Synchronize | SemaphoreRights.Modify, 
                    AccessControlType.Deny);
                semSec.RemoveAccessRule(rule);

                // Now grant the user the correct rights.
                // 
                rule = new SemaphoreAccessRule(user, 
                     SemaphoreRights.Synchronize | SemaphoreRights.Modify, 
                     AccessControlType.Allow);
                semSec.AddAccessRule(rule);

                // Update the ACL. This requires
                // SemaphoreRights.ChangePermissions.
                sem.SetAccessControl(semSec);

                Console.WriteLine("Updated semaphore security.");

                // Open the semaphore with (SemaphoreRights.Synchronize 
                // | SemaphoreRights.Modify), the rights required to
                // enter and release the semaphore.
                //
                sem = Semaphore.OpenExisting(semaphoreName);
            }
            catch(UnauthorizedAccessException ex)
            {
                Console.WriteLine("Unable to change permissions: {0}", ex.Message);
                return;
            }
        }

        // Enter the semaphore, and hold it until the program
        // exits.
        //
        try
        {
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore.");
            Console.WriteLine("Press the Enter key to exit.");
            Console.ReadLine();
            sem.Release();
        }
        catch(UnauthorizedAccessException ex)
        {
            Console.WriteLine("Unauthorized access: {0}", ex.Message);
        }
    }
}
Imports System.Threading
Imports System.Security.AccessControl

Friend Class Example

    <MTAThread> _
    Friend Shared Sub Main()
        Const semaphoreName As String = "SemaphoreExample5"

        Dim sem As Semaphore = Nothing
        Dim doesNotExist as Boolean = False
        Dim unauthorized As Boolean = False

        ' Attempt to open the named semaphore.
        Try
            ' Open the semaphore with (SemaphoreRights.Synchronize
            ' Or SemaphoreRights.Modify), to enter and release the
            ' named semaphore.
            '
            sem = Semaphore.OpenExisting(semaphoreName)
        Catch ex As WaitHandleCannotBeOpenedException
            Console.WriteLine("Semaphore does not exist.")
            doesNotExist = True
        Catch ex As UnauthorizedAccessException
            Console.WriteLine("Unauthorized access: {0}", ex.Message)
            unauthorized = True
        End Try

        ' There are three cases: (1) The semaphore does not exist.
        ' (2) The semaphore exists, but the current user doesn't 
        ' have access. (3) The semaphore exists and the user has
        ' access.
        '
        If doesNotExist Then
            ' The semaphore does not exist, so create it.
            '
            ' The value of this variable is set by the semaphore
            ' constructor. It is True if the named system semaphore was
            ' created, and False if the named semaphore already existed.
            '
            Dim semaphoreWasCreated As Boolean

            ' Create an access control list (ACL) that denies the
            ' current user the right to enter or release the 
            ' semaphore, but allows the right to read and change
            ' security information for the semaphore.
            '
            Dim user As String = Environment.UserDomainName _ 
                & "\" & Environment.UserName
            Dim semSec As New SemaphoreSecurity()

            Dim rule As New SemaphoreAccessRule(user, _
                SemaphoreRights.Synchronize Or SemaphoreRights.Modify, _
                AccessControlType.Deny)
            semSec.AddAccessRule(rule)

            rule = New SemaphoreAccessRule(user, _
                SemaphoreRights.ReadPermissions Or _
                SemaphoreRights.ChangePermissions, _
                AccessControlType.Allow)
            semSec.AddAccessRule(rule)

            ' Create a Semaphore object that represents the system
            ' semaphore named by the constant 'semaphoreName', with
            ' maximum count three, initial count three, and the
            ' specified security access. The Boolean value that 
            ' indicates creation of the underlying system object is
            ' placed in semaphoreWasCreated.
            '
            sem = New Semaphore(3, 3, semaphoreName, _
                semaphoreWasCreated, semSec)

            ' If the named system semaphore was created, it can be
            ' used by the current instance of this program, even 
            ' though the current user is denied access. The current
            ' program enters the semaphore. Otherwise, exit the
            ' program.
            ' 
            If semaphoreWasCreated Then
                Console.WriteLine("Created the semaphore.")
            Else
                Console.WriteLine("Unable to create the semaphore.")
                Return
            End If

        ElseIf unauthorized Then

            ' Open the semaphore to read and change the access
            ' control security. The access control security defined
            ' above allows the current user to do this.
            '
            Try
                sem = Semaphore.OpenExisting(semaphoreName, _
                    SemaphoreRights.ReadPermissions Or _
                    SemaphoreRights.ChangePermissions)

                ' Get the current ACL. This requires 
                ' SemaphoreRights.ReadPermissions.
                Dim semSec As SemaphoreSecurity = sem.GetAccessControl()
                
                Dim user As String = Environment.UserDomainName _ 
                    & "\" & Environment.UserName

                ' First, the rule that denied the current user 
                ' the right to enter and release the semaphore must
                ' be removed.
                Dim rule As New SemaphoreAccessRule(user, _
                    SemaphoreRights.Synchronize Or SemaphoreRights.Modify, _
                    AccessControlType.Deny)
                semSec.RemoveAccessRule(rule)

                ' Now grant the user the correct rights.
                ' 
                rule = New SemaphoreAccessRule(user, _
                    SemaphoreRights.Synchronize Or SemaphoreRights.Modify, _
                    AccessControlType.Allow)
                semSec.AddAccessRule(rule)

                ' Update the ACL. This requires
                ' SemaphoreRights.ChangePermissions.
                sem.SetAccessControl(semSec)

                Console.WriteLine("Updated semaphore security.")

                ' Open the semaphore with (SemaphoreRights.Synchronize 
                ' Or SemaphoreRights.Modify), the rights required to
                ' enter and release the semaphore.
                '
                sem = Semaphore.OpenExisting(semaphoreName)

            Catch ex As UnauthorizedAccessException
                Console.WriteLine("Unable to change permissions: {0}", _
                    ex.Message)
                Return
            End Try

        End If

        ' Enter the semaphore, and hold it until the program
        ' exits.
        '
        Try
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore.")
            Console.WriteLine("Press the Enter key to exit.")
            Console.ReadLine()
            sem.Release()
        Catch ex As UnauthorizedAccessException
            Console.WriteLine("Unauthorized access: {0}", _
                ex.Message)
        End Try
    End Sub 
End Class

備註

使用此建構子在命名系統信號量建立時,對其施加存取控制安全性,防止其他程式碼控制該信號量。

可以name以 或 Global\ 作為前綴Local\,以指定命名空間。 當 Global 命名空間被指定時,同步物件可以與系統上的任何程序共享。 當 Local 指定命名空間時(這也是未指定命名空間時的預設),同步物件可能會與同一會話中的程序共享。 在 Windows 上,會話是登入會話,服務通常在不同的非互動會話中執行。 在類 Unix 作業系統中,每個 shell 都有自己的會話。 會話本地同步物件可能適合在具有父/子關係且所有程序都在同一會話中執行的程序間同步。 欲了解更多關於Windows同步物件名稱的資訊,請參見 Object Names

如果已提供 a name ,且命名空間中已有該請求類型的同步物件,則會使用現有的同步物件。 如果命名空間中已有不同類型的同步物件,則會拋出 a WaitHandleCannotBeOpenedException 。 否則,會建立一個新的同步物件。

此建構器初始化一個 Semaphore 代表命名系統信號量的物件。 你可以建立多個 Semaphore 物件,代表同一個命名的系統信號量。

若命名系統信號量不存在,則以指定的存取控制安全性建立。 若存在命名的信號量,則忽略指定的存取控制安全性。

備註

即使Semaphore呼叫者拒絕或未授予當前使用者部分存取權限,仍能完全控制新建立semaphoreSecurity的物件。 然而,如果目前使用者嘗試使用構造子或 Semaphore 方法,取得另一個 OpenExisting 物件來表示同一個名稱的信號量,則會套用Windows存取控制安全性。

若系統中不存在命名的信號量,則以初始數量及最大數量為 initialCountmaximumCount和 來建立。 若已命名系統的信號量存在且 initialCountmaximumCount 未被使用,即使值無效仍會產生例外。 利用參數 createdNew 判斷系統的信號量是否由此建構器產生。

initialCountmaximumCount於 ,且 createdNewtrue,效果與當前執行緒呼叫WaitOnemaximumCount次數(減initialCount去)相同。

如果你指定 null 或 一個空字串 , name會產生一個局部的信號量,就像你呼叫 Semaphore(Int32, Int32) 了建構子過載一樣。 在此情況下, createdNew 總是 true

由於命名的信號量在整個作業系統中可見,因此可用來協調跨流程邊界的資源使用。

Caution

預設情況下,命名的信號量不限於創建它的使用者。 其他使用者可能能夠開啟並使用信號旗,包括多次取得信號旗卻不釋放來干擾信號量。 要限制特定使用者的存取,你可以在建立命名信號旗時傳遞 a SemaphoreSecurity 。 避免在可能有不受信任使用者執行程式碼的系統中使用無存取限制的命名信號量。

另請參閱

適用於

Semaphore(Int32, Int32, String, NamedWaitHandleOptions, Boolean)

來源:
Semaphore.cs
來源:
Semaphore.cs

初始化該類別的新實例 Semaphore ,指定初始條目數及最大並行條目數,可選擇性地指定系統信號量物件名稱及設定使用者範圍與會話範圍存取的選項,並指定一個變數接收值,表示是否建立了新的系統信號量。

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name, System::Threading::NamedWaitHandleOptions options, [Runtime::InteropServices::Out] bool % createdNew);
public Semaphore(int initialCount, int maximumCount, string? name, System.Threading.NamedWaitHandleOptions options, out bool createdNew);
new System.Threading.Semaphore : int * int * string * System.Threading.NamedWaitHandleOptions * bool -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String, options As NamedWaitHandleOptions, ByRef createdNew As Boolean)

參數

initialCount
Int32

可同時滿足的旗量初始請求數量。

maximumCount
Int32

同時可滿足的最大信號量請求數。

name
String

若同步物件要與其他程序共享,則使用名稱;否則, null 或空字串。 名稱會區分大小寫。

options
NamedWaitHandleOptions

命名信號板的範圍選項。 預設權限僅限於目前使用者和當前會話。 指定的選項可能會影響名稱的命名空間以及對底層信號量物件的存取。

createdNew
Boolean

當此方法回傳時,包含 true 若已建立本地信號量(即 name 是 或 null 空字串),或是否建立了指定的命名系統信號量;包含 false 該指定命名系統信號量已存在。 這個參數會未初始化傳遞。

例外狀況

initialCount 大於 maximumCount

-或-

initialCount 小於0。

name 無效。 這可能有各種原因,包括作業系統可能施加的一些限制,例如未知的前綴或無效字元。 請注意,名稱及常見前綴「Global\」與「Local\」皆為大小寫區分。

-或-

還有其他錯誤。 房產 HResult 可能會提供更多資訊。

Windows 僅有:name 指定了一個未知命名空間。 更多資訊請參閱 物件名稱

name太長了。 長度限制可能依作業系統或設定而異。

命名的信號量存在且具備存取控制安全性,而使用者則沒有 FullControl

無法建立與所提供的 name 同步物件。 不同類型的同步物件可能名稱相同。

-或-

存在具有指定 name 條件的物件,但指定的 options 物件與現有物件的選項不相容。

備註

若已提供 a name ,且命名空間中已有該類型的同步物件,則使用現有的同步物件,除非 options 指定存取權限僅限當前使用者且同步物件與其不相容,此時會拋出 a WaitHandleCannotBeOpenedException 。 如果命名空間中已經存在不同類型的同步物件,也會拋出 a WaitHandleCannotBeOpenedException 。 否則,會建立一個新的同步物件。

此建構器初始化一個 Semaphore 代表命名系統信號量的物件。 你可以建立多個 Semaphore 物件,代表同一個命名的系統信號量。

若系統中不存在命名的信號量,則以初始數量及最大數量為 initialCountmaximumCount和 來建立。 若已命名系統的信號量存在且 initialCountmaximumCount 未被使用,即使值無效仍會產生例外。 利用參數 createdNew 判斷系統的信號量是否由此建構器產生。

initialCountmaximumCount於 ,且 createdNewtrue,效果與當前執行緒呼叫WaitOnemaximumCount次數(減initialCount去)相同。

如果你指定 null 或 一個空字串 , name會產生一個局部的信號量,就像你呼叫 Semaphore(Int32, Int32) 了建構子過載一樣。 在此情況下, createdNew 總是 true

由於命名的信號量在整個作業系統中可見,因此可用來協調跨流程邊界的資源使用。

在Windows上,可以提供options來指定該命名的信號量是僅對當前使用者開放,還是所有使用者都能存取。 它也允許你指定命名的信號量是只對當前會話中的程序可存取,還是所有會話都能存取。 如需詳細資訊,請參閱NamedWaitHandleOptions

Caution

在基於 Unix 的作業系統中,該 options 參數不影響,因為不支援命名的信號量。

另請參閱

適用於