SemaphoreSlim Sınıf

Tanım

Bir kaynağa veya kaynak havuzuna Semaphore eşzamanlı olarak erişebilecek iş parçacığı sayısını sınırlayan basit bir alternatifi temsil eder.

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
Devralma
SemaphoreSlim
Öznitelikler
Uygulamalar

Örnekler

Aşağıdaki örnek, en fazla üç iş parçacığı ve ilk sayısı sıfır iş parçacığı olan bir semafor oluşturur. Örnek, tümü semaforu bekleyen blok olan beş görev başlatır. Ana iş parçacığı, semafor sayısını maksimuma yükseltmek için aşırı yüklemeyi çağırır Release(Int32) ve bu da üç görevi semafora girmesini sağlar. Semafor her serbest bırakıldığında, önceki semafor sayısı görüntülenir. Konsol iletileri semafor kullanımını izler. Simülasyon çalışma aralığı, çıkışın okunmasını kolaylaştırmak için her iş parçacığı için biraz artırılır.

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.

Açıklamalar

Semaforlar iki türdendir: yerel semaforlar ve adlandırılmış sistem semaforları. Yerel semaforlar bir uygulama için yereldir, sistem semaforları işletim sistemi genelinde görünür ve işlemler arası eşitleme için uygundur. SemaphoreSlim, çekirdek semaforları Windows kullanmayan sınıfına basit bir alternatiftirSemaphore. sınıfından Semaphore farklı olarak SemaphoreSlim , sınıf adlandırılmış sistem semaforlarını desteklemez. Bunu yalnızca yerel bir semafor olarak kullanabilirsiniz. sınıfı SemaphoreSlim , tek bir uygulama içinde eşitleme için önerilen semafordur.

Hafif bir semafor, uygulamanız için yerel olan bir kaynak havuzuna erişimi denetler. Bir semafor örneği oluştururken, semaforu eşzamanlı olarak girebilecek en fazla iş parçacığı sayısını belirtebilirsiniz. Ayrıca semaforu eşzamanlı olarak girebilen ilk iş parçacığı sayısını da belirtirsiniz. Bu, semafor sayısını tanımlar.

Bir iş parçacığı semafora her girdiğinde sayı düşer ve bir iş parçacığı semaforu her serbest bıraktığında artırılır. Semafor girmek için, bir iş parçacığı veya WaitAsync aşırı yüklemelerinden Wait birini çağırır. Semaforu serbest bırakmak için aşırı yüklemelerden Release birini çağırır. Sayı sıfıra ulaştığında, diğer iş parçacıkları semaforu Wait serbest bırakana kadar yöntemlerden birine yapılan sonraki çağrılar engellenir. Birden çok iş parçacığı engellenirse, iş parçacıklarının semafora ne zaman girdiğini denetleyen FIFO veya LIFO gibi garantili bir düzen yoktur.

Kaynakları korumak için semafor kullanan kodun temel yapısı:

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

Tüm iş parçacıkları semaforu serbest bırakıldığında, sayı semafor oluşturulduğunda belirtilen en yüksek değerde olur. Semafor'un sayısı özelliğinden CurrentCount kullanılabilir.

Önemli

SemaphoreSlim sınıfı, , WaitAsyncve Release yöntemlerine Waityapılan çağrılarda iş parçacığı veya görev kimliğini zorlamaz. Buna ek olarak, oluşturucu nesnesinin SemaphoreSlim örneğini oluşturmak için kullanılırsaSemaphoreSlim(Int32), CurrentCount özellik oluşturucu tarafından ayarlanan değerin ötesinde artabilir. veya WaitAsync yöntemlerine yapılan çağrıların yöntemlere Wait yapılan çağrılarla uygun şekilde eşlendiğinden emin olmak programcının Release sorumluluğundadır.

Oluşturucular

SemaphoreSlim(Int32)

Eşzamanlı olarak verilebilen ilk istek sayısını belirterek sınıfının yeni bir örneğini SemaphoreSlim başlatır.

SemaphoreSlim(Int32, Int32)

Sınıfının yeni bir örneğini SemaphoreSlim başlatır ve eşzamanlı olarak verilebilen ilk ve en fazla istek sayısını belirtir.

Özellikler

AvailableWaitHandle

Semafor üzerinde beklemek için kullanılabilecek bir WaitHandle döndürür.

CurrentCount

Nesneyi girebilen kalan iş parçacıklarının SemaphoreSlim sayısını alır.

Yöntemler

Dispose()

SemaphoreSlim sınıfının geçerli örneği tarafından kullanılan tüm kaynakları serbest bırakır.

Dispose(Boolean)

tarafından SemaphoreSlimkullanılan yönetilmeyen kaynakları serbest bırakır ve isteğe bağlı olarak yönetilen kaynakları serbest bırakır.

Equals(Object)

Belirtilen nesnenin geçerli nesneye eşit olup olmadığını belirler.

(Devralındığı yer: Object)
GetHashCode()

Varsayılan karma işlevi işlevi görür.

(Devralındığı yer: Object)
GetType()

Type Geçerli örneğini alır.

(Devralındığı yer: Object)
MemberwiseClone()

Geçerli Objectöğesinin sığ bir kopyasını oluşturur.

(Devralındığı yer: Object)
Release()

SemaphoreSlim Nesneyi bir kez serbest bırakır.

Release(Int32)

SemaphoreSlim Nesneyi belirtilen sayıda serbest bırakır.

ToString()

Geçerli nesneyi temsil eden dizeyi döndürür.

(Devralındığı yer: Object)
Wait()

Geçerli iş parçacığını girebilene SemaphoreSlimkadar engeller.

Wait(CancellationToken)

Geçerli iş parçacığını, bir CancellationTokengözlemlerken içine girene SemaphoreSlimkadar engeller.

Wait(Int32)

Zaman aşımını belirten 32 bit imzalı bir tamsayı kullanarak girebilene SemaphoreSlimkadar geçerli iş parçacığını engeller.

Wait(Int32, CancellationToken)

Geçerli iş parçacığını, bir gözlemlerken zaman aşımını SemaphoreSlimbelirten 32 bit imzalı tamsayı kullanarak girebilene CancellationTokenkadar engeller.

Wait(TimeSpan)

Zaman aşımını belirtmek için kullanarak TimeSpan , girebilene SemaphoreSlimkadar geçerli iş parçacığını engeller.

Wait(TimeSpan, CancellationToken)

Geçerli iş parçacığını, zaman aşımını SemaphoreSlimbelirten bir TimeSpan kullanarak ve gözlemlerken girebilene CancellationTokenkadar engeller.

WaitAsync()

zaman uyumsuz olarak girmek SemaphoreSlimiçin bekler.

WaitAsync(CancellationToken)

bir gözlemlerken CancellationTokenzaman uyumsuz olarak girmek SemaphoreSlimiçin bekler.

WaitAsync(Int32)

Zaman aralığını ölçmek için 32 bit imzalı bir tamsayı kullanarak zaman uyumsuz olarak girmek SemaphoreSlimiçin bekler.

WaitAsync(Int32, CancellationToken)

zaman uyumsuz olarak girmek SemaphoreSlimiçin bekler ve zaman aralığını ölçerken 32 bit imzalı bir tamsayı kullanarak bir CancellationTokengözlemler.

WaitAsync(TimeSpan)

zaman aralığını ölçmek için kullanarak TimeSpan zaman uyumsuz olarak girmek SemaphoreSlimiçin bekler.

WaitAsync(TimeSpan, CancellationToken)

zaman uyumsuz olarak girmek SemaphoreSlimiçin bekler ve zaman aralığını ölçmek için kullanarak TimeSpan bir CancellationTokengözlemler.

Şunlara uygulanır

İş Parçacığı Güvenliği

tüm genel ve korumalı üyeleri SemaphoreSlim iş parçacığı açısından güvenlidir ve yalnızca üzerindeki diğer tüm işlemler SemaphoreSlim tamamlandığında kullanılması gereken dışında Dispose()birden çok iş parçacığından eşzamanlı olarak kullanılabilir.

Ayrıca bkz.