ManualResetEventSlim Klasa

Definicja

Reprezentuje zdarzenie synchronizacji wątków, które po zasygnalizowanej sytuacji musi zostać zresetowane ręcznie. Ta klasa jest lekką alternatywą dla ManualResetEventklasy .

public ref class ManualResetEventSlim : IDisposable
public class ManualResetEventSlim : IDisposable
[System.Runtime.InteropServices.ComVisible(false)]
public class ManualResetEventSlim : IDisposable
type ManualResetEventSlim = class
    interface IDisposable
[<System.Runtime.InteropServices.ComVisible(false)>]
type ManualResetEventSlim = class
    interface IDisposable
Public Class ManualResetEventSlim
Implements IDisposable
Dziedziczenie
ManualResetEventSlim
Atrybuty
Implementuje

Przykłady

W poniższym przykładzie pokazano, jak używać funkcji ManualResetEventSlim.

using System;
using System.Threading;
using System.Threading.Tasks;
class MRESDemo
{

    static void Main()
    {
        MRES_SetWaitReset();
        MRES_SpinCountWaitHandle();
    }
    // Demonstrates:
    //      ManualResetEventSlim construction
    //      ManualResetEventSlim.Wait()
    //      ManualResetEventSlim.Set()
    //      ManualResetEventSlim.Reset()
    //      ManualResetEventSlim.IsSet
    static void MRES_SetWaitReset()
    {
        ManualResetEventSlim mres1 = new ManualResetEventSlim(false); // initialize as unsignaled
        ManualResetEventSlim mres2 = new ManualResetEventSlim(false); // initialize as unsignaled
        ManualResetEventSlim mres3 = new ManualResetEventSlim(true);  // initialize as signaled

        // Start an asynchronous Task that manipulates mres3 and mres2
        var observer = Task.Factory.StartNew(() =>
        {
            mres1.Wait();
            Console.WriteLine("observer sees signaled mres1!");
            Console.WriteLine("observer resetting mres3...");
            mres3.Reset(); // should switch to unsignaled
            Console.WriteLine("observer signalling mres2");
            mres2.Set();
        });

        Console.WriteLine("main thread: mres3.IsSet = {0} (should be true)", mres3.IsSet);
        Console.WriteLine("main thread signalling mres1");
        mres1.Set(); // This will "kick off" the observer Task
        mres2.Wait(); // This won't return until observer Task has finished resetting mres3
        Console.WriteLine("main thread sees signaled mres2!");
        Console.WriteLine("main thread: mres3.IsSet = {0} (should be false)", mres3.IsSet);

        // It's good form to Dispose() a ManualResetEventSlim when you're done with it
        observer.Wait(); // make sure that this has fully completed
        mres1.Dispose();
        mres2.Dispose();
        mres3.Dispose();
    }

    // Demonstrates:
    //      ManualResetEventSlim construction w/ SpinCount
    //      ManualResetEventSlim.WaitHandle
    static void MRES_SpinCountWaitHandle()
    {
        // Construct a ManualResetEventSlim with a SpinCount of 1000
        // Higher spincount => longer time the MRES will spin-wait before taking lock
        ManualResetEventSlim mres1 = new ManualResetEventSlim(false, 1000);
        ManualResetEventSlim mres2 = new ManualResetEventSlim(false, 1000);

        Task bgTask = Task.Factory.StartNew(() =>
        {
            // Just wait a little
            Thread.Sleep(100);

            // Now signal both MRESes
            Console.WriteLine("Task signalling both MRESes");
            mres1.Set();
            mres2.Set();
        });

        // A common use of MRES.WaitHandle is to use MRES as a participant in 
        // WaitHandle.WaitAll/WaitAny.  Note that accessing MRES.WaitHandle will
        // result in the unconditional inflation of the underlying ManualResetEvent.
        WaitHandle.WaitAll(new WaitHandle[] { mres1.WaitHandle, mres2.WaitHandle });
        Console.WriteLine("WaitHandle.WaitAll(mres1.WaitHandle, mres2.WaitHandle) completed.");

        // Clean up
        bgTask.Wait();
        mres1.Dispose();
        mres2.Dispose();
    }
}
Imports System.Threading
Imports System.Threading.Tasks

Module MRESDemo

    Sub Main()

    End Sub
    ' Demonstrates:
    ' ManualResetEventSlim construction
    ' ManualResetEventSlim.Wait()
    ' ManualResetEventSlim.Set()
    ' ManualResetEventSlim.Reset()
    ' ManualResetEventSlim.IsSet
    Private Sub MRES_SetWaitReset()
        ' initialize as unsignaled
        Dim mres1 As New ManualResetEventSlim(False)
        ' initialize as unsignaled
        Dim mres2 As New ManualResetEventSlim(False)
        ' initialize as signaled
        Dim mres3 As New ManualResetEventSlim(True)

        ' Start an asynchronous Task that manipulates mres3 and mres2
        Dim observer = Task.Factory.StartNew(
            Sub()
                mres1.Wait()
                Console.WriteLine("observer sees signaled mres1!")
                Console.WriteLine("observer resetting mres3...")
                mres3.Reset()
                ' should switch to unsignaled
                Console.WriteLine("observer signalling mres2")
                mres2.[Set]()
            End Sub)

        Console.WriteLine("main thread: mres3.IsSet = {0} (should be true)", mres3.IsSet)
        Console.WriteLine("main thread signalling mres1")
        mres1.[Set]()
        ' This will "kick off" the observer Task
        mres2.Wait()
        ' This won't return until observer Task has finished resetting mres3
        Console.WriteLine("main thread sees signaled mres2!")
        Console.WriteLine("main thread: mres3.IsSet = {0} (should be false)", mres3.IsSet)

        ' make sure that observer has fully completed
        observer.Wait()
        ' It's good form to Dispose() a ManualResetEventSlim when you're done with it
        mres1.Dispose()
        mres2.Dispose()
        mres3.Dispose()
    End Sub

    ' Demonstrates:
    ' ManualResetEventSlim construction w/ SpinCount
    ' ManualResetEventSlim.WaitHandle
    Private Sub MRES_SpinCountWaitHandle()
        ' Construct a ManualResetEventSlim with a SpinCount of 1000
        ' Higher spincount => longer time the MRES will spin-wait before taking lock
        Dim mres1 As New ManualResetEventSlim(False, 1000)
        Dim mres2 As New ManualResetEventSlim(False, 1000)

        Dim bgTask As Task = Task.Factory.StartNew(
            Sub()
                ' Just wait a little
                Thread.Sleep(100)

                ' Now signal both MRESes
                Console.WriteLine("Task signalling both MRESes")
                mres1.[Set]()
                mres2.[Set]()
            End Sub)

        ' A common use of MRES.WaitHandle is to use MRES as a participant in 
        ' WaitHandle.WaitAll/WaitAny. Note that accessing MRES.WaitHandle will
        ' result in the unconditional inflation of the underlying ManualResetEvent.
        WaitHandle.WaitAll(New WaitHandle() {mres1.WaitHandle, mres2.WaitHandle})
        Console.WriteLine("WaitHandle.WaitAll(mres1.WaitHandle, mres2.WaitHandle) completed.")

        ' Wait for bgTask to complete and clean up
        bgTask.Wait()
        mres1.Dispose()
        mres2.Dispose()
    End Sub
End Module

Uwagi

Tej klasy można użyć w celu uzyskania lepszej wydajności niż ManualResetEvent wtedy, gdy oczekuje się, że czas oczekiwania będzie bardzo krótki, a zdarzenie nie przekracza granicy procesu. ManualResetEventSlim używa zajętego wirowania przez krótki czas, podczas gdy oczekuje na zdarzenie, aby zasygnalizować. Gdy czas oczekiwania jest krótki, obracanie może być znacznie tańsze niż oczekiwanie przy użyciu uchwytów oczekiwania. Jeśli jednak wydarzenie nie zostanie zasygnalizowane w określonym czasie, ManualResetEventSlim ucieka się do regularnego oczekiwania na obsługę zdarzeń.

Uwaga

W programach .NET Core i .NET 5+domyślny czas oczekiwania na spin jest krótki: w kolejności 10 mikrosekund w zależności od platformy i procesora. Jeśli spodziewasz się, że czasy oczekiwania będą znacznie dłuższe, nadal możesz użyć tej klasy zamiast ManualResetEvent (być może skonfigurowane z mniejszą lub bez oczekiwania). Jednak korzyść z wydajności byłaby prawdopodobnie tylko marginalna.

Konstruktory

ManualResetEventSlim()

Inicjuje ManualResetEventSlim nowe wystąpienie klasy z początkowym stanem niepodpisanym.

ManualResetEventSlim(Boolean)

Inicjuje ManualResetEventSlim nowe wystąpienie klasy z wartością logiczną wskazującą, czy ustawić stan początkowy na sygnalizowany.

ManualResetEventSlim(Boolean, Int32)

Inicjuje nowe wystąpienie ManualResetEventSlim klasy z wartością logiczną wskazującą, czy ustawić początkowy stan na sygnalizowany i określoną liczbę spinów.

Właściwości

IsSet

Pobiera informacje o tym, czy zdarzenie jest ustawione.

SpinCount

Pobiera liczbę kolejek, które wystąpią przed powrotem do operacji oczekiwania opartej na jądrze.

WaitHandle

Pobiera obiekt bazowy WaitHandle dla tego ManualResetEventSlimobiektu .

Metody

Dispose()

Zwalnia wszystkie zasoby używane przez bieżące wystąpienie klasy ManualResetEventSlim.

Dispose(Boolean)

Zwalnia niezarządzane zasoby używane przez ManualResetEventSlimprogram i opcjonalnie zwalnia zarządzane zasoby.

Equals(Object)

Określa, czy dany obiekt jest taki sam, jak bieżący obiekt.

(Odziedziczone po Object)
GetHashCode()

Służy jako domyślna funkcja skrótu.

(Odziedziczone po Object)
GetType()

Type Pobiera wartość bieżącego wystąpienia.

(Odziedziczone po Object)
MemberwiseClone()

Tworzy płytkią kopię bieżącego Objectelementu .

(Odziedziczone po Object)
Reset()

Ustawia stan zdarzenia na niepodpisany, co powoduje zablokowanie wątków.

Set()

Ustawia stan zdarzenia na sygnalizowany, co umożliwia kontynuowanie co najmniej jednego wątku oczekującego na zdarzenie.

ToString()

Zwraca ciąg reprezentujący bieżący obiekt.

(Odziedziczone po Object)
Wait()

Blokuje bieżący wątek do momentu ustawienia bieżącego ManualResetEventSlim .

Wait(CancellationToken)

Blokuje bieżący wątek, dopóki bieżący ManualResetEventSlim nie odbierze sygnału, obserwując CancellationTokenelement .

Wait(Int32)

Blokuje bieżący wątek do momentu ustawienia bieżącego ManualResetEventSlim , używając 32-bitowej liczby całkowitej ze znakiem, aby zmierzyć interwał czasu.

Wait(Int32, CancellationToken)

Blokuje bieżący wątek do momentu ustawienia bieżącego ManualResetEventSlim , używając 32-bitowej liczby całkowitej ze znakiem CancellationTokendo pomiaru interwału czasu, obserwując wartość .

Wait(TimeSpan)

Blokuje bieżący wątek do momentu ustawienia bieżącego ManualResetEventSlim przy użyciu elementu , TimeSpan aby zmierzyć interwał czasu.

Wait(TimeSpan, CancellationToken)

Blokuje bieżący wątek do momentu ustawienia bieżącego ManualResetEventSlim przy użyciu elementu , TimeSpan aby zmierzyć interwał czasu, obserwując CancellationTokenelement .

Dotyczy

Bezpieczeństwo wątkowe

Wszystkie publiczne i chronione elementy ManualResetEventSlim członkowskie są bezpieczne wątkowo i mogą być używane współbieżnie z wielu wątków, z wyjątkiem Dispose, które muszą być używane tylko wtedy, gdy wszystkie inne operacje na ManualResetEventSlim obiekcie zostały ukończone, i Resetuj, które powinny być używane tylko wtedy, gdy żadne inne wątki nie uzyskują dostępu do zdarzenia.

Zobacz też