Sdílet prostřednictvím


SemaphoreSlim Třída

Definice

Představuje odlehčenou alternativu k Semaphore omezení počtu vláken, která můžou současně přistupovat k prostředku nebo fondu prostředků.

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
Dědičnost
SemaphoreSlim
Atributy
Implementuje

Příklady

Následující příklad vytvoří semaphore s maximálním počtem tří vláken a počátečním počtem nulových vláken. Příklad spustí pět úkolů, z nichž všechny bloky čekají na semafor. Hlavní vlákno volá Release(Int32) přetížení ke zvýšení počtu semaphore na jeho maximum, což umožňuje třem úkolům zadat semafor. Při každém uvolnění semaforu se zobrazí předchozí semafor. Zprávy konzoly sledují použití semaphore. Simulovaný pracovní interval se pro každé vlákno mírně zvýší, aby se výstup snadněji četl.

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.

Poznámky

Semafory jsou dvou typů: místní semaphores a pojmenované systémové semafory. Místní semafory jsou místní pro aplikaci, systémové semafory jsou viditelné v celém operačním systému a jsou vhodné pro synchronizaci mezi procesy. Jedná se SemaphoreSlim o odlehčenou alternativu Semaphore ke třídě, která nepoužívá semafory jádra Windows. Semaphore Na rozdíl od třídy SemaphoreSlim třída nepodporuje pojmenované systémové semafory. Můžete ho použít jenom jako místní semafor. Třída SemaphoreSlim je doporučenou semaphore pro synchronizaci v rámci jedné aplikace.

Jednoduchý semaphore řídí přístup k fondu prostředků, který je místní pro vaši aplikaci. Při vytváření instance semaphore můžete zadat maximální počet vláken, která mohou zadat semafor souběžně. Zadáte také počáteční počet vláken, která mohou současně zadat semafor. Tím se definuje počet semaphore.

Počet se sníží pokaždé, když vlákno vstoupí do semaforu a zvýší se pokaždé, když vlákno uvolní semafor. Chcete-li zadat semaphore, vlákno volá jedno z Wait přetížení.WaitAsync Chcete-li uvolnit semaphore, volá jedno z Release přetížení. Když počet dosáhne nuly, následné volání jedné z Wait metod blokují, dokud ostatní vlákna uvolní semaphore. Pokud je blokováno více vláken, neexistuje žádné zaručené pořadí, například FIFO nebo LIFO, které řídí, když vlákna vstoupí do semaphore.

Základní struktura kódu, který používá k ochraně prostředků semaphore, je:

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

Když všechna vlákna uvolní semaphore, počet je maximální hodnota zadaná při vytvoření semaforu. Počet semaphore je k dispozici ve CurrentCount vlastnosti.

Důležité

Třída SemaphoreSlim nevynucuje identitu vlákna nebo úlohy při volání WaitWaitAsync, a Release metody. Kromě toho, pokud SemaphoreSlim(Int32) konstruktor je použit k vytvoření instance SemaphoreSlim objektu, CurrentCount vlastnost může zvýšit nad hodnotu nastavenou konstruktorem. Je zodpovědností programátora zajistit, aby volání nebo WaitWaitAsync metody byly odpovídajícím způsobem spárovány s voláními Release metod.

Konstruktory

Name Description
SemaphoreSlim(Int32, Int32)

Inicializuje novou instanci SemaphoreSlim třídy a určuje počáteční a maximální počet požadavků, které lze udělit současně.

SemaphoreSlim(Int32)

Inicializuje novou instanci SemaphoreSlim třídy a určuje počáteční počet požadavků, které lze udělit souběžně.

Vlastnosti

Name Description
AvailableWaitHandle

WaitHandle Vrátí hodnotu, kterou lze použít k čekání na semafor.

CurrentCount

Získá počet zbývajících vláken, které mohou zadat SemaphoreSlim objekt.

Metody

Name Description
Dispose()

Uvolní všechny prostředky používané aktuální instancí SemaphoreSlim třídy.

Dispose(Boolean)

Uvolní nespravované prostředky používané SemaphoreSlimnástrojem a volitelně uvolní spravované prostředky.

Equals(Object)

Určuje, zda je zadaný objekt roven aktuálnímu objektu.

(Zděděno od Object)
GetHashCode()

Slouží jako výchozí funkce hash.

(Zděděno od Object)
GetType()

Získá Type aktuální instance.

(Zděděno od Object)
MemberwiseClone()

Vytvoří mělkou kopii aktuálního Object.

(Zděděno od Object)
Release()

SemaphoreSlim Uvolní objekt jednou.

Release(Int32)

SemaphoreSlim Uvolní objekt zadaný početkrát.

ToString()

Vrátí řetězec, který představuje aktuální objekt.

(Zděděno od Object)
Wait()

Zablokuje aktuální vlákno, dokud nebude moci vstoupit do SemaphoreSlim.

Wait(CancellationToken)

Blokuje aktuální vlákno, dokud nemůže vstoupit do SemaphoreSlim, při sledování CancellationToken.

Wait(Int32, CancellationToken)

Blokuje aktuální vlákno, dokud nemůže zadat SemaphoreSlim, pomocí 32bitového signed integer, který určuje časový limit při sledování CancellationToken.

Wait(Int32)

Zablokuje aktuální vlákno, dokud nemůže zadat SemaphoreSlim, pomocí 32bitového signed integer, který určuje časový limit.

Wait(TimeSpan, CancellationToken)

Zablokuje aktuální vlákno, dokud nemůže vstoupit do SemaphoreSlim, pomocí TimeSpan , který určuje časový limit, při sledování CancellationToken.

Wait(TimeSpan)

Zablokuje aktuální vlákno, dokud nebude moci zadat SemaphoreSlim, pomocí parametru a TimeSpan určete časový limit.

WaitAsync()

Asynchronně čeká na zadání .SemaphoreSlim

WaitAsync(CancellationToken)

Asynchronně čeká na vstup , SemaphoreSlimpři sledování CancellationToken.

WaitAsync(Int32, CancellationToken)

Asynchronně čeká na zadání SemaphoreSlim, pomocí 32bitového signed integer k měření časového intervalu při pozorování CancellationToken.

WaitAsync(Int32)

Asynchronně čeká na zadání SemaphoreSlim, pomocí 32bitového signed integer k měření časového intervalu.

WaitAsync(TimeSpan, CancellationToken)

Asynchronně čeká na zadání SemaphoreSlim, pomocí aměřte TimeSpan časový interval při pozorování CancellationToken.

WaitAsync(TimeSpan)

Asynchronně čeká na zadání SemaphoreSlim, pomocí aměřte TimeSpan časový interval.

Platí pro

Bezpečný přístup z více vláken

Všechny veřejné a chráněné členy SemaphoreSlim jsou bezpečné pro přístup z více vláken a mohou být použity souběžně z více vláken, s výjimkou Dispose(), které se musí použít pouze v případě, že byly dokončeny všechny ostatní operace SemaphoreSlim .

Viz také