WaitHandle Klasa

Definicja

Hermetyzuje obiekty specyficzne dla systemu operacyjnego, które oczekują na wyłączny dostęp do zasobów udostępnionych.

public ref class WaitHandle abstract : IDisposable
public ref class WaitHandle abstract : MarshalByRefObject, IDisposable
public abstract class WaitHandle : IDisposable
public abstract class WaitHandle : MarshalByRefObject, IDisposable
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class WaitHandle : MarshalByRefObject, IDisposable
type WaitHandle = class
    interface IDisposable
type WaitHandle = class
    inherit MarshalByRefObject
    interface IDisposable
[<System.Runtime.InteropServices.ComVisible(true)>]
type WaitHandle = class
    inherit MarshalByRefObject
    interface IDisposable
Public MustInherit Class WaitHandle
Implements IDisposable
Public MustInherit Class WaitHandle
Inherits MarshalByRefObject
Implements IDisposable
Dziedziczenie
WaitHandle
Dziedziczenie
Pochodne
Atrybuty
Implementuje

Przykłady

Poniższy przykład kodu pokazuje, jak dwa wątki mogą wykonywać zadania w tle, podczas gdy wątek Główny czeka na ukończenie zadań przy użyciu statycznych WaitAny i WaitAll metod WaitHandle klasy.

using namespace System;
using namespace System::Threading;

public ref class WaitHandleExample
{
    // Define a random number generator for testing.
private:
    static Random^ random = gcnew Random();
public:
    static void DoTask(Object^ state)
    {
        AutoResetEvent^ autoReset = (AutoResetEvent^) state;
        int time = 1000 * random->Next(2, 10);
        Console::WriteLine("Performing a task for {0} milliseconds.", time);
        Thread::Sleep(time);
        autoReset->Set();
    }
};

int main()
{
    // Define an array with two AutoResetEvent WaitHandles.
    array<WaitHandle^>^ handles = gcnew array<WaitHandle^> {
        gcnew AutoResetEvent(false), gcnew AutoResetEvent(false)};

    // Queue up two tasks on two different threads;
    // wait until all tasks are completed.
    DateTime timeInstance = DateTime::Now;
    Console::WriteLine("Main thread is waiting for BOTH tasks to " +
        "complete.");
    ThreadPool::QueueUserWorkItem(
        gcnew WaitCallback(WaitHandleExample::DoTask), handles[0]);
    ThreadPool::QueueUserWorkItem(
        gcnew WaitCallback(WaitHandleExample::DoTask), handles[1]);
    WaitHandle::WaitAll(handles);
    // The time shown below should match the longest task.
    Console::WriteLine("Both tasks are completed (time waited={0})",
        (DateTime::Now - timeInstance).TotalMilliseconds);

    // Queue up two tasks on two different threads;
    // wait until any tasks are completed.
    timeInstance = DateTime::Now;
    Console::WriteLine();
    Console::WriteLine("The main thread is waiting for either task to " +
        "complete.");
    ThreadPool::QueueUserWorkItem(
        gcnew WaitCallback(WaitHandleExample::DoTask), handles[0]);
    ThreadPool::QueueUserWorkItem(
        gcnew WaitCallback(WaitHandleExample::DoTask), handles[1]);
    int index = WaitHandle::WaitAny(handles);
    // The time shown below should match the shortest task.
    Console::WriteLine("Task {0} finished first (time waited={1}).",
        index + 1, (DateTime::Now - timeInstance).TotalMilliseconds);
}

// This code produces the following sample output.
//
// Main thread is waiting for BOTH tasks to complete.
// Performing a task for 7000 milliseconds.
// Performing a task for 4000 milliseconds.
// Both tasks are completed (time waited=7064.8052)

// The main thread is waiting for either task to complete.
// Performing a task for 2000 milliseconds.
// Performing a task for 2000 milliseconds.
// Task 1 finished first (time waited=2000.6528).
using System;
using System.Threading;

public sealed class App
{
    // Define an array with two AutoResetEvent WaitHandles.
    static WaitHandle[] waitHandles = new WaitHandle[]
    {
        new AutoResetEvent(false),
        new AutoResetEvent(false)
    };

    // Define a random number generator for testing.
    static Random r = new Random();

    static void Main()
    {
        // Queue up two tasks on two different threads;
        // wait until all tasks are completed.
        DateTime dt = DateTime.Now;
        Console.WriteLine("Main thread is waiting for BOTH tasks to complete.");
        ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
        ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
        WaitHandle.WaitAll(waitHandles);
        // The time shown below should match the longest task.
        Console.WriteLine("Both tasks are completed (time waited={0})",
            (DateTime.Now - dt).TotalMilliseconds);

        // Queue up two tasks on two different threads;
        // wait until any task is completed.
        dt = DateTime.Now;
        Console.WriteLine();
        Console.WriteLine("The main thread is waiting for either task to complete.");
        ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
        ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
        int index = WaitHandle.WaitAny(waitHandles);
        // The time shown below should match the shortest task.
        Console.WriteLine("Task {0} finished first (time waited={1}).",
            index + 1, (DateTime.Now - dt).TotalMilliseconds);
    }

    static void DoTask(Object state)
    {
        AutoResetEvent are = (AutoResetEvent) state;
        int time = 1000 * r.Next(2, 10);
        Console.WriteLine("Performing a task for {0} milliseconds.", time);
        Thread.Sleep(time);
        are.Set();
    }
}

// This code produces output similar to the following:
//
//  Main thread is waiting for BOTH tasks to complete.
//  Performing a task for 7000 milliseconds.
//  Performing a task for 4000 milliseconds.
//  Both tasks are completed (time waited=7064.8052)
//
//  The main thread is waiting for either task to complete.
//  Performing a task for 2000 milliseconds.
//  Performing a task for 2000 milliseconds.
//  Task 1 finished first (time waited=2000.6528).
Imports System.Threading

NotInheritable Public Class App
    ' Define an array with two AutoResetEvent WaitHandles.
    Private Shared waitHandles() As WaitHandle = _
        {New AutoResetEvent(False), New AutoResetEvent(False)}
    
    ' Define a random number generator for testing.
    Private Shared r As New Random()
    
    <MTAThreadAttribute> _
    Public Shared Sub Main() 
        ' Queue two tasks on two different threads; 
        ' wait until all tasks are completed.
        Dim dt As DateTime = DateTime.Now
        Console.WriteLine("Main thread is waiting for BOTH tasks to complete.")
        ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(0))
        ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(1))
        WaitHandle.WaitAll(waitHandles)
        ' The time shown below should match the longest task.
        Console.WriteLine("Both tasks are completed (time waited={0})", _
            (DateTime.Now - dt).TotalMilliseconds)
        
        ' Queue up two tasks on two different threads; 
        ' wait until any tasks are completed.
        dt = DateTime.Now
        Console.WriteLine()
        Console.WriteLine("The main thread is waiting for either task to complete.")
        ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(0))
        ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(1))
        Dim index As Integer = WaitHandle.WaitAny(waitHandles)
        ' The time shown below should match the shortest task.
        Console.WriteLine("Task {0} finished first (time waited={1}).", _
            index + 1,(DateTime.Now - dt).TotalMilliseconds)
    
    End Sub
    
    Shared Sub DoTask(ByVal state As [Object]) 
        Dim are As AutoResetEvent = CType(state, AutoResetEvent)
        Dim time As Integer = 1000 * r.Next(2, 10)
        Console.WriteLine("Performing a task for {0} milliseconds.", time)
        Thread.Sleep(time)
        are.Set()
    
    End Sub
End Class

' This code produces output similar to the following:
'
'  Main thread is waiting for BOTH tasks to complete.
'  Performing a task for 7000 milliseconds.
'  Performing a task for 4000 milliseconds.
'  Both tasks are completed (time waited=7064.8052)
' 
'  The main thread is waiting for either task to complete.
'  Performing a task for 2000 milliseconds.
'  Performing a task for 2000 milliseconds.
'  Task 1 finished first (time waited=2000.6528).

Uwagi

Klasa WaitHandle hermetyzuje uchwyt synchronizacji natywnego systemu operacyjnego i służy do reprezentowania wszystkich obiektów synchronizacji w środowisku uruchomieniowym, które zezwalają na wiele operacji oczekiwania. Aby zapoznać się z porównaniem dojść oczekiwania z innymi obiektami synchronizacji, zobacz Omówienie elementów pierwotnych synchronizacji.

Sama klasa jest abstrakcyjna WaitHandle . Klasy pochodzące z WaitHandle definiowania mechanizmu sygnalizacyjnego wskazującego na pobieranie lub zwalnianie dostępu do zasobu udostępnionego, ale używają dziedziczonej WaitHandle metody do blokowania podczas oczekiwania na dostęp do zasobów udostępnionych. Klasy pochodne WaitHandle obejmują:

Wątki mogą blokować pojedynczy uchwyt oczekiwania przez wywołanie metody WaitOnewystąpienia , która jest dziedziczona przez klasy pochodzące z WaitHandleklasy .

Klasy pochodne WaitHandle różnią się koligacją wątku. Dojścia oczekiwania zdarzeń (EventWaitHandle, AutoResetEvent, i ) i ManualResetEventsemafory nie mają koligacji wątku; każdy wątek może sygnalizować uchwyt oczekiwania zdarzenia lub semafor. Z drugiej strony, mutexes mają koligację wątku; wątek, który jest właścicielem mutex musi go zwolnić, a wyjątek jest zgłaszany, jeśli wątek wywołuje ReleaseMutex metodę na mutex, którego nie jest właścicielem.

WaitHandle Ponieważ klasa pochodzi z MarshalByRefObjectklasy , te klasy mogą służyć do synchronizowania działań wątków poza granicami domeny aplikacji.

Oprócz klas pochodnych klasa WaitHandle ma wiele metod statycznych, które blokują wątek, dopóki co najmniej jeden obiekt synchronizacji nie otrzyma sygnału. Są one następujące:

  • SignalAndWait, dzięki czemu wątek może sygnalizować jeden uchwyt oczekiwania i natychmiast czekać na inny.

  • WaitAll, dzięki czemu wątek może czekać, aż wszystkie dojścia oczekiwania w tablicy otrzymają sygnał.

  • WaitAny, dzięki czemu wątek może czekać, aż zostanie zasygnalizowany jeden z określonego zestawu dojść oczekiwania.

Przeciążenia tych metod zapewniają interwały limitu czasu dla porzucenia oczekiwania oraz możliwość zakończenia kontekstu synchronizacji przed wprowadzeniem oczekiwania, co umożliwia innym wątkom korzystanie z kontekstu synchronizacji.

Ważne

Ten typ implementuje IDisposable interfejs. Po zakończeniu korzystania z typu lub typu pochodnego należy usunąć go bezpośrednio lub pośrednio. Aby bezpośrednio usunąć typ, wywołaj jego Close metodę try/catch w bloku. Aby usunąć go pośrednio, użyj konstrukcji języka, takiej jak using (w języku C#) lub Using (w Visual Basic). Aby uzyskać więcej informacji, zobacz sekcję "Using an Object that Implements IDisposable" (Używanie obiektu implementujące interfejs IDisposable) w temacie interfejsu IDisposable .

WaitHandle implementuje Dispose wzorzec. Zobacz Implementowanie metody Dispose. Gdy pochodzisz z WaitHandleklasy , użyj właściwości do przechowywania natywnego SafeWaitHandle dojścia systemu operacyjnego. Nie trzeba zastępować chronionej Dispose metody, chyba że używasz dodatkowych zasobów niezarządzanych.

Konstruktory

WaitHandle()

Inicjuje nowe wystąpienie klasy WaitHandle.

Pola

InvalidHandle

Reprezentuje nieprawidłowy natywny uchwyt systemu operacyjnego. To pole jest tylko do odczytu.

WaitTimeout

Wskazuje, że WaitAny(WaitHandle[], Int32, Boolean) upłynął limit czasu operacji, zanim którykolwiek z dojść oczekiwania został zasygnalizowany. To pole jest stałe.

Właściwości

Handle
Przestarzałe.
Przestarzałe.

Pobiera lub ustawia natywny uchwyt systemu operacyjnego.

SafeWaitHandle

Pobiera lub ustawia natywny uchwyt systemu operacyjnego.

Metody

Close()

Zwalnia wszystkie zasoby przechowywane przez bieżący WaitHandleelement .

CreateObjRef(Type)

Tworzy obiekt zawierający wszystkie istotne informacje wymagane do wygenerowania serwera proxy używanego do komunikowania się z obiektem zdalnym.

(Odziedziczone po MarshalByRefObject)
Dispose()

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

Dispose(Boolean)

Po zastąpieniu w klasie pochodnej zwalnia niezarządzane zasoby używane przez klasę WaitHandlei opcjonalnie zwalniają zarządzane zasoby.

Equals(Object)

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

(Odziedziczone po Object)
Finalize()

Zwalnia zasoby blokowane przez bieżące wystąpienie.

GetHashCode()

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

(Odziedziczone po Object)
GetLifetimeService()
Przestarzałe.

Pobiera bieżący obiekt usługi okresu istnienia, który kontroluje zasady okresu istnienia dla tego wystąpienia.

(Odziedziczone po MarshalByRefObject)
GetType()

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

(Odziedziczone po Object)
InitializeLifetimeService()
Przestarzałe.

Uzyskuje obiekt usługi okresu istnienia w celu kontrolowania zasad okresu istnienia dla tego wystąpienia.

(Odziedziczone po MarshalByRefObject)
MemberwiseClone()

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

(Odziedziczone po Object)
MemberwiseClone(Boolean)

Tworzy płytkią kopię bieżącego MarshalByRefObject obiektu.

(Odziedziczone po MarshalByRefObject)
SignalAndWait(WaitHandle, WaitHandle)

Sygnalizuje jeden WaitHandle i czeka na inny.

SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)

Sygnalizuje jeden WaitHandle i czeka na inny, określając interwał limitu czasu jako 32-bitową liczbę całkowitą ze znakiem i określając, czy zamknąć domenę synchronizacji dla kontekstu przed wprowadzeniem oczekiwania.

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

Sygnalizuje jeden WaitHandle i czeka na inny, określając interwał limitu czasu jako i TimeSpan określając, czy zamknąć domenę synchronizacji dla kontekstu przed wprowadzeniem oczekiwania.

ToString()

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

(Odziedziczone po Object)
WaitAll(WaitHandle[])

Oczekuje, aż wszystkie elementy w określonej tablicy otrzymają sygnał.

WaitAll(WaitHandle[], Int32)

Oczekuje, aż wszystkie elementy w określonej tablicy otrzymają sygnał, używając Int32 wartości w celu określenia interwału czasu.

WaitAll(WaitHandle[], Int32, Boolean)

Oczekuje na odebranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu Int32 wartości w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

WaitAll(WaitHandle[], TimeSpan)

Oczekuje, aż wszystkie elementy w określonej tablicy otrzymają sygnał, używając TimeSpan wartości w celu określenia interwału czasu.

WaitAll(WaitHandle[], TimeSpan, Boolean)

Oczekuje, aż wszystkie elementy w określonej tablicy otrzymają sygnał, używając TimeSpan wartości w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

WaitAny(WaitHandle[])

Oczekuje na odebranie sygnału przez dowolny element w określonej tablicy.

WaitAny(WaitHandle[], Int32)

Oczekuje, aż dowolny element w określonej tablicy otrzyma sygnał, używając 32-bitowej liczby całkowitej ze znakiem w celu określenia interwału czasu.

WaitAny(WaitHandle[], Int32, Boolean)

Oczekuje, aż dowolny element w określonej tablicy otrzyma sygnał, używając 32-bitowej liczby całkowitej ze znakiem w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

WaitAny(WaitHandle[], TimeSpan)

Oczekuje na odebranie sygnału przez dowolny element w określonej tablicy przy użyciu parametru , TimeSpan aby określić przedział czasu.

WaitAny(WaitHandle[], TimeSpan, Boolean)

Oczekuje na odebranie sygnału przez dowolny element w określonej tablicy przy użyciu parametru w TimeSpan celu określenia przedziału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

WaitOne()

Blokuje bieżący wątek, dopóki bieżący WaitHandle nie otrzyma sygnału.

WaitOne(Int32)

Blokuje bieżący wątek do momentu odebrania sygnału WaitHandle przy użyciu 32-bitowej liczby całkowitej ze znakiem w celu określenia interwału czasu w milisekundach.

WaitOne(Int32, Boolean)

Blokuje bieżący wątek do momentu WaitHandle odebrania sygnału przy użyciu 32-bitowej liczby całkowitej ze znakiem w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

WaitOne(TimeSpan)

Blokuje bieżący wątek do momentu odebrania sygnału przez bieżące wystąpienie przy użyciu parametru w TimeSpan celu określenia interwału czasu.

WaitOne(TimeSpan, Boolean)

Blokuje bieżący wątek do momentu odebrania sygnału przez bieżące wystąpienie przy użyciu parametru w TimeSpan celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

Jawne implementacje interfejsu

IDisposable.Dispose()

Ten interfejs API obsługuje infrastrukturę produktu i nie jest przeznaczony do użycia bezpośrednio z poziomu kodu.

Zwalnia wszelkie zasoby używane przez element WaitHandle.

Metody rozszerzania

GetSafeWaitHandle(WaitHandle)

Pobiera bezpieczny uchwyt dla natywnego uchwytu oczekiwania systemu operacyjnego.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Ustawia bezpieczny uchwyt dla natywnego uchwytu oczekiwania systemu operacyjnego.

Dotyczy

Bezpieczeństwo wątkowe

Ten typ jest bezpieczny wątkowo.

Zobacz też