SemaphoreSlim Klass

Definition

Representerar ett enkelt alternativ till Semaphore som begränsar antalet trådar som kan komma åt en resurs eller resurspool samtidigt.

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
Arv
SemaphoreSlim
Attribut
Implementeringar

Exempel

I följande exempel skapas en semafor med maximalt antal tre trådar och ett initialt antal noll trådar. Exemplet startar fem uppgifter, som alla blockerar väntan på semaforen. Huvudtråden anropar överbelastningen Release(Int32) för att öka semaforantalet till sitt maximala, vilket gör att tre uppgifter kan ange semaforen. Varje gång semaforen släpps visas det tidigare semaforantalet. Konsolmeddelanden spårar semaforanvändning. Det simulerade arbetsintervallet ökar något för varje tråd för att göra utdata lättare att läsa.

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.

Kommentarer

Semaforer är av två typer: lokala semaphores och namngivna systemskarmaforer. Lokala semaforer är lokala för ett program, systemsemaforer visas i hela operativsystemet och är lämpliga för synkronisering mellan processer. SemaphoreSlim är ett enkelt alternativ till klassen Semaphore som inte använder Windows kernel-semaforer. Semaphore Till skillnad från klassen SemaphoreSlim stöder klassen inte namngivna systemsemaforer. Du kan endast använda den som lokal semafor. Klassen SemaphoreSlim är den rekommenderade semaforen för synkronisering i en enda app.

En lätt semafor styr åtkomsten till en pool med resurser som är lokal för ditt program. När du instansierar en semafor kan du ange det maximala antalet trådar som kan ange semafor samtidigt. Du anger också det inledande antalet trådar som kan ange semafor samtidigt. Detta definierar antalet semaforer.

Antalet minskas varje gång en tråd går in i semaforen och ökas varje gång en tråd släpper ut semaforen. För att ange semaforen anropar en tråd en av Wait eller WaitAsync överlagringarna. För att frigöra semaforen anropar den en av överlagringarna Release . När antalet når noll anropas efterföljande anrop till en av Wait metoderna tills andra trådar släpper semaforen. Om flera trådar blockeras finns det ingen garanterad ordning, till exempel FIFO eller LIFO, som styr när trådarna kommer in i semaforen.

Den grundläggande strukturen för kod som använder en semafor för att skydda resurser är:

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

När alla trådar har släppt semaforen är antalet vid det högsta värde som angavs när semaforen skapades. Semaforens antal är tillgängligt från boendet CurrentCount .

Important

Klassen SemaphoreSlim framtvingar inte tråd- eller uppgiftsidentitet vid anrop till Waitmetoderna , WaitAsyncoch Release . Om konstruktorn används för att instansiera SemaphoreSlim objektet CurrentCount kan egenskapen dessutom SemaphoreSlim(Int32) öka utöver det värde som konstruktorn anger. Det är programmerarens ansvar att se till att anrop till Wait eller WaitAsync metoder är korrekt kopplade till anrop till Release metoder.

Konstruktorer

Name Description
SemaphoreSlim(Int32, Int32)

Initierar en ny instans av SemaphoreSlim klassen och anger det inledande och maximala antalet begäranden som kan beviljas samtidigt.

SemaphoreSlim(Int32)

Initierar en ny instans av SemaphoreSlim klassen och anger det inledande antalet begäranden som kan beviljas samtidigt.

Egenskaper

Name Description
AvailableWaitHandle

Returnerar en WaitHandle som kan användas för att vänta på semaforen.

CurrentCount

Hämtar antalet återstående trådar som kan ange objektet SemaphoreSlim .

Metoder

Name Description
Dispose()

Släpper alla resurser som används av den aktuella instansen SemaphoreSlim av klassen.

Dispose(Boolean)

Släpper de ohanterade resurser som används av SemaphoreSlim, och släpper eventuellt de hanterade resurserna.

Equals(Object)

Avgör om det angivna objektet är lika med det aktuella objektet.

(Ärvd från Object)
GetHashCode()

Fungerar som standard-hash-funktion.

(Ärvd från Object)
GetType()

Hämtar den aktuella instansen Type .

(Ärvd från Object)
MemberwiseClone()

Skapar en ytlig kopia av den aktuella Object.

(Ärvd från Object)
Release()

Släpper objektet SemaphoreSlim en gång.

Release(Int32)

Släpper ut SemaphoreSlim objektet ett angivet antal gånger.

ToString()

Returnerar en sträng som representerar det aktuella objektet.

(Ärvd från Object)
Wait()

Blockerar den aktuella tråden tills den SemaphoreSlimkan ange .

Wait(CancellationToken)

Blockerar den aktuella tråden tills den SemaphoreSlimkan ange , medan du observerar en CancellationToken.

Wait(Int32, CancellationToken)

Blockerar den aktuella tråden tills den SemaphoreSlimkan ange , med hjälp av ett 32-bitars signerat heltal som anger tidsgränsen, samtidigt som en CancellationToken.

Wait(Int32)

Blockerar den aktuella tråden tills den SemaphoreSlimkan ange , med ett 32-bitars signerat heltal som anger tidsgränsen.

Wait(TimeSpan, CancellationToken)

Blockerar den aktuella tråden tills den SemaphoreSlimkan ange , med hjälp av en TimeSpan som anger tidsgränsen, medan du observerar en CancellationToken.

Wait(TimeSpan)

Blockerar den aktuella tråden tills den SemaphoreSlimkan ange , med hjälp av a TimeSpan för att ange tidsgränsen.

WaitAsync()

Väntar asynkront på att ange SemaphoreSlim.

WaitAsync(CancellationToken)

Väntar asynkront på att ange SemaphoreSlim, medan du observerar en CancellationToken.

WaitAsync(Int32, CancellationToken)

Väntar asynkront på att ange SemaphoreSlim, med hjälp av ett 32-bitars signerat heltal för att mäta tidsintervallet, medan du observerar ett CancellationToken.

WaitAsync(Int32)

Väntar asynkront på att ange SemaphoreSlim, med hjälp av ett 32-bitars signerat heltal för att mäta tidsintervallet.

WaitAsync(TimeSpan, CancellationToken)

Väntar asynkront på att ange SemaphoreSlim, med hjälp av en TimeSpan för att mäta tidsintervallet, medan du observerar en CancellationToken.

WaitAsync(TimeSpan)

Väntar asynkront på att ange SemaphoreSlim, med hjälp av en TimeSpan för att mäta tidsintervallet.

Gäller för

Trådsäkerhet

Alla offentliga och skyddade medlemmar SemaphoreSlim i är trådsäkra och kan användas samtidigt från flera trådar, med undantag för Dispose(), som endast får användas när alla andra åtgärder på SemaphoreSlim har slutförts.

Se även