SemaphoreSlim Třída

Definice

Představuje jednoduchou alternativu k Semaphore omezení počtu vláken, která můžou současně přistupovat k prostředkům 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ž každý blok čeká na semafor. Hlavní vlákno volá Release(Int32) přetížení ke zvýšení počtu semaphore na jeho maximum, což umožňuje tři úkoly vstoupit do semaforu. Při každém uvolnění semaforu se zobrazí předchozí počet semaforů. Zprávy konzoly sledují použití semaphore. Simulovaný pracovní interval se mírně zvýší pro každé vlákno, 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 dva typy: 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á SemaphoreSlim se o jednoduchou alternativu Semaphore třídy, která nepoužívá Windows semaphores jádra. Semaphore Na rozdíl od třídy SemaphoreSlim třída nepodporuje pojmenované systémové semaphores. Můžete ho použít pouze jako místní semafor. Třída SemaphoreSlim je doporučeným semaphorem pro synchronizaci v rámci jedné aplikace.

Jednoduchý semaphore řídí přístup k fondu prostředků, které jsou místní pro vaši aplikaci. Při vytvoření instance semaforu můžete určit maximální počet vláken, které mohou současně zadat semafor. Zadáte také počáteční počet vláken, která mohou současně zadat semaphore. 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á jeden z Wait přetížení.WaitAsync Chcete-li uvolnit semaphore, volá jednu 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í, jako je FIFO nebo LIFO, které řídí, když vlákna vstoupí do semaforu.

Základní struktura kódu, který k ochraně prostředků používá 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í Wait, WaitAsynca Release metody. Kromě toho, pokud SemaphoreSlim(Int32) konstruktor se používá k vytvoření instance SemaphoreSlim objektu, CurrentCount může vlastnost zvýšit nad hodnotu nastavenou konstruktorem. Je zodpovědností programátora zajistit, aby se volání metod Wait nebo WaitAsync metod odpovídajícím způsobem spárovala s voláními Release metod.

Konstruktory

SemaphoreSlim(Int32)

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

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 souběžně.

Vlastnosti

AvailableWaitHandle

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

CurrentCount

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

Metody

Dispose()

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

Dispose(Boolean)

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

Equals(Object)

Určí, zda se zadaný objekt rovná aktuálnímu objektu.

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

Slouží jako výchozí funkce hash.

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

Type Získá aktuální instanci.

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

Vytvoří použádnou kopii aktuálního souboru 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 nemůže vstoupit do SemaphoreSlim.

Wait(CancellationToken)

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

Wait(Int32)

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

Wait(Int32, CancellationToken)

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

Wait(TimeSpan)

Zablokuje aktuální vlákno, dokud nebude moct zadat SemaphoreSlim, pomocí TimeSpan časového limitu.

Wait(TimeSpan, CancellationToken)

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

WaitAsync()

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

WaitAsync(CancellationToken)

Asynchronně čeká na vstup SemaphoreSlimdo , při pozorování CancellationToken.

WaitAsync(Int32)

Asynchronně čeká na zadání SemaphoreSlim32bitového celého čísla se signtegerem, který měří časový interval.

WaitAsync(Int32, CancellationToken)

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

WaitAsync(TimeSpan)

Asynchronně počká na zadání SemaphoreSlim, pomocí měření TimeSpan časového intervalu.

WaitAsync(TimeSpan, CancellationToken)

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

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é