SemaphoreSlim Osztály

Definíció

Ez egy egyszerű alternatívát Semaphore jelent, amely korlátozza az erőforrásokhoz vagy erőforráskészletekhez egyidejűleg hozzáférő szálak számát.

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
Öröklődés
SemaphoreSlim
Attribútumok
Megvalósítás

Példák

Az alábbi példa egy legfeljebb három szálból álló szemafortot hoz létre, amelynek kezdeti száma nulla. A példa öt feladatot indít el, amelyek mindegyike a szemapóra vár. A fő szál meghívja a Release(Int32) túlterhelést, hogy növelje a szemaphore számát a maximális értékre, ami lehetővé teszi három feladat belépését a szemaforba. Minden alkalommal, amikor a szemaphore felszabadul, megjelenik az előző szemaphore-szám. A konzolüzenetek nyomon követik a szemaphore használatát. A szimulált munkaintervallum kismértékben növekszik minden szál esetében, hogy a kimenet könnyebben olvasható legyen.

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.

Megjegyzések

A szemaphorok két típusból állnak: a helyi szemaforok és a nevesített rendszer-szemaphorok. A helyi szemaphorok helyiek az alkalmazásokhoz, a rendszerszemforok az operációs rendszer egészében láthatók, és alkalmasak a folyamatok közötti szinkronizálásra. A SemaphoreSlim a Semaphore osztály egyszerű alternatívája, amely nem használ Windows kernel-szemaphorokat. Az Semaphore osztálytól eltérően az osztály nem támogatja a SemaphoreSlim nevesített rendszerszemforokat. Csak helyi szemaforként használhatja. Az SemaphoreSlim osztály az egyetlen alkalmazáson belüli szinkronizáláshoz ajánlott szemaphore.

A könnyű szemaphore az alkalmazás helyi erőforráskészletéhez való hozzáférést szabályozza. A szemaforok példányosításakor megadhatja az egyidejűleg beírható szálak maximális számát. Meg kell adnia a szemaphore egyidejűleg beírható szálak kezdeti számát is. Ez határozza meg a szemaphore számát.

A darabszám minden alkalommal csökken, amikor egy szál belép a szemaforba, és minden alkalommal növekszik, amikor egy szál felszabadítja a szemaphore-t. A szemapóba való belépéshez egy szál meghívja az Wait egyik vagy WaitAsync túlterhelést. A szemaphore felszabadításához az egyik túlterhelést Release hívja. Amikor a szám eléri a nullát, az Wait egyik metódushoz érkező későbbi hívások blokkolják, amíg más szálak fel nem oldják a szemaphore-t. Ha több szál is blokkolva van, nincs garantált sorrend, például a FIFO vagy a LIFO, amely szabályozza, hogy a szálak mikor lépnek be a szemaforba.

Az erőforrások védelmére szemafortot használó kód alapstruktúrája a következő:

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

Amikor az összes szál kiadta a szemaphore-t, a szám a szemafor létrehozásakor megadott maximális értéken van megadva. A semaphore száma elérhető a CurrentCount tulajdonságból.

Important

Az SemaphoreSlim osztály nem kényszeríti ki a szálat vagy a tevékenységidentitást a , Waités WaitAsync metódusok Releasehívásaihoz. Emellett, ha a SemaphoreSlim(Int32) konstruktort az objektum példányosítására SemaphoreSlim használják, a CurrentCount tulajdonság a konstruktor által beállított értéken túl is növekedhet. A programozó feladata annak biztosítása, hogy a hívásokat Wait vagy WaitAsync metódusokat megfelelően párosítsa a metódusokra Release irányuló hívásokkal.

Konstruktorok

Name Description
SemaphoreSlim(Int32, Int32)

Inicializálja az SemaphoreSlim osztály új példányát, megadva az egyidejűleg megadható kérelmek kezdeti és maximális számát.

SemaphoreSlim(Int32)

Inicializálja az SemaphoreSlim osztály új példányát, megadva az egyidejűleg megadható kérelmek kezdeti számát.

Tulajdonságok

Name Description
AvailableWaitHandle

Olyan értéket WaitHandle ad vissza, amely a szemapóra várakozásához használható.

CurrentCount

Lekéri az objektumba beírható SemaphoreSlim fennmaradó szálak számát.

Metódusok

Name Description
Dispose()

Az osztály aktuális példánya által használt összes erőforrást felszabadítja SemaphoreSlim .

Dispose(Boolean)

Felszabadítja a felügyelt erőforrások által SemaphoreSlimhasznált nem felügyelt erőforrásokat, és opcionálisan felszabadítja a felügyelt erőforrásokat.

Equals(Object)

Meghatározza, hogy a megadott objektum egyenlő-e az aktuális objektummal.

(Öröklődés forrása Object)
GetHashCode()

Ez az alapértelmezett kivonatoló függvény.

(Öröklődés forrása Object)
GetType()

Lekéri az Type aktuális példányt.

(Öröklődés forrása Object)
MemberwiseClone()

Az aktuális Objectpéldány sekély másolatát hozza létre.

(Öröklődés forrása Object)
Release()

Egyszer felszabadítja az SemaphoreSlim objektumot.

Release(Int32)

Adott számú alkalommal oldja fel az SemaphoreSlim objektumot.

ToString()

Az aktuális objektumot jelképező sztringet ad vissza.

(Öröklődés forrása Object)
Wait()

Letiltja az aktuális szálat, amíg be nem léphet a SemaphoreSlim.

Wait(CancellationToken)

Blokkolja az aktuális szálat, amíg be nem léphet a SemaphoreSlim, miközben megfigyeli a CancellationToken.

Wait(Int32, CancellationToken)

Letiltja az aktuális szálat, amíg be nem léphet a SemaphoreSlimmezőbe egy 32 bites aláírt egész szám használatával, amely megadja az időtúllépést, miközben megfigyel egy CancellationToken.

Wait(Int32)

Letiltja az aktuális szálat, amíg be nem léphet a SemaphoreSlimfolyamatba egy 32 bites aláírt egész szám használatával, amely megadja az időtúllépést.

Wait(TimeSpan, CancellationToken)

Letiltja az aktuális szálat, amíg be nem léphet a SemaphoreSlim, az időtúllépést meghatározó paranccsal TimeSpan , miközben megfigyel egy CancellationToken.

Wait(TimeSpan)

Letiltja az aktuális szálat, amíg be nem léphet a SemaphoreSlim, az időtúllépés megadásához használva TimeSpan .

WaitAsync()

Aszinkron módon megvárja a beírást SemaphoreSlim.

WaitAsync(CancellationToken)

Aszinkron módon megvárja a beírást SemaphoreSlim, miközben megfigyel egy CancellationToken.

WaitAsync(Int32, CancellationToken)

Aszinkron módon megvárja a beírást egy SemaphoreSlim32 bites aláírt egész számmal az időintervallum méréséhez, miközben megfigyel egy CancellationToken.

WaitAsync(Int32)

Aszinkron módon megvárja a beírást egy SemaphoreSlim32 bites aláírt egész számmal az időintervallum méréséhez.

WaitAsync(TimeSpan, CancellationToken)

Aszinkron módon megvárja a beírást az SemaphoreSlimTimeSpan időintervallum mérésére, miközben megfigyel egy CancellationToken.

WaitAsync(TimeSpan)

Aszinkron módon megvárja a beírást az SemaphoreSlimidőintervallum mérésére használt aszinkron TimeSpan módon.

A következőre érvényes:

Szálbiztonság

Az összes nyilvános és védett tag SemaphoreSlim szálbiztos, és egyidejűleg több szálból is használható, kivéve Dispose()azt, amely csak akkor használható, ha az SemaphoreSlim összes többi művelet befejeződött.

Lásd még