Condividi tramite


WaitHandle Classe

Definizione

Incapsula oggetti specifici del sistema operativo che attendono l'accesso esclusivo alle risorse condivise.

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
Ereditarietà
WaitHandle
Ereditarietà
Derivato
Attributi
Implementazioni

Esempio

Nell'esempio di codice seguente viene illustrato come due thread possono eseguire attività in background mentre il thread Main attende il completamento delle attività usando i metodi e WaitAll statici WaitAny della WaitHandle classe .

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).

Commenti

La WaitHandle classe incapsula un handle di sincronizzazione del sistema operativo nativo e viene usata per rappresentare tutti gli oggetti di sincronizzazione nel runtime che consentono più operazioni di attesa. Per un confronto degli handle di attesa con altri oggetti di sincronizzazione, vedere Panoramica delle primitive di sincronizzazione.

La WaitHandle classe stessa è astratta. Le classi derivate da WaitHandle definiscono un meccanismo di segnalazione per indicare l'acquisizione o il rilascio dell'accesso a una risorsa condivisa, ma usano i metodi ereditati WaitHandle per bloccare l'attesa dell'accesso alle risorse condivise. Le classi derivate da WaitHandle includono:

I thread possono bloccarsi in un singolo handle di attesa chiamando il metodo WaitOnedi istanza , ereditato dalle classi derivate da WaitHandle.

Le classi derivate di WaitHandle differiscono nell'affinità di thread. Gli handle di attesa degli eventi (EventWaitHandle, AutoResetEvente ) e ManualResetEventi semafori non hanno affinità di thread. Qualsiasi thread può segnalare un handle di attesa degli eventi o un semaforo. I mutex, d'altra parte, hanno affinità di thread; il thread proprietario di un mutex deve rilasciarlo e viene generata un'eccezione se un thread chiama il ReleaseMutex metodo su un mutex che non è proprietario.

Poiché la WaitHandle classe deriva da MarshalByRefObject, queste classi possono essere usate per sincronizzare le attività dei thread attraverso i limiti del dominio applicazione.

Oltre alle classi derivate, la WaitHandle classe dispone di diversi metodi statici che bloccano un thread fino a quando uno o più oggetti di sincronizzazione non ricevono un segnale. Sono inclusi:

  • SignalAndWait, che consente a un thread di segnalare un handle di attesa e attendere immediatamente su un altro.

  • WaitAll, che consente a un thread di attendere fino a quando tutti gli handle di attesa in una matrice ricevono un segnale.

  • WaitAny, che consente a un thread di attendere fino a quando non viene segnalato uno dei set di handle di attesa specificati.

Gli overload di questi metodi forniscono intervalli di timeout per abbandonare l'attesa e la possibilità di uscire da un contesto di sincronizzazione prima di entrare nell'attesa, consentendo ad altri thread di usare il contesto di sincronizzazione.

Importante

Il tipo implementa l'interfaccia IDisposable. Al termine dell'utilizzo del tipo o di un tipo derivato, è necessario eliminarlo direttamente o indirettamente. Per eliminare direttamente il tipo, chiamare il metodo Close in un blocco try/catch. Per eliminarlo indirettamente, utilizzare un costrutto di linguaggio come ad esempio using in C# o Using in Visual Basic. Per altre informazioni, vedere la sezione "Uso di un oggetto che implementa IDisposable" nell'argomento relativo all'interfaccia IDisposable.

WaitHandle implementa il Dispose modello. Vedere Implementazione di un metodo Dispose. Quando si deriva da WaitHandle, usare la proprietà per archiviare l'handle SafeWaitHandle del sistema operativo nativo. Non è necessario eseguire l'override del metodo protetto Dispose , a meno che non si usino risorse aggiuntive non gestite.

Costruttori

WaitHandle()

Inizializza una nuova istanza della classe WaitHandle.

Campi

InvalidHandle

Rappresenta un handle nativo del sistema operativo non valido. Questo campo è di sola lettura.

WaitTimeout

Indica che si è verificato il timeout di un'operazione WaitAny(WaitHandle[], Int32, Boolean) prima della segnalazione di uno degli handle di attesa. Questo campo è costante.

Proprietà

Handle
Obsoleti.
Obsoleti.

Ottiene o imposta l'handle nativo del sistema operativo.

SafeWaitHandle

Ottiene o imposta l'handle nativo del sistema operativo.

Metodi

Close()

Rilascia tutte le risorse contenute nell'oggetto WaitHandle corrente.

CreateObjRef(Type)

Consente di creare un oggetto che contiene tutte le informazioni rilevanti necessarie per la generazione del proxy utilizzato per effettuare la comunicazione con un oggetto remoto.

(Ereditato da MarshalByRefObject)
Dispose()

Rilascia tutte le risorse usate dall'istanza corrente della classe WaitHandle.

Dispose(Boolean)

Quando ne viene eseguito l'override in una classe derivata, libera le risorse non gestite usate da WaitHandle ed eventualmente di liberare le risorse gestite.

Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.

(Ereditato da Object)
Finalize()

Rilascia le risorse contenute nell'istanza corrente.

GetHashCode()

Funge da funzione hash predefinita.

(Ereditato da Object)
GetLifetimeService()
Obsoleti.

Consente di recuperare l'oggetto servizio di durata corrente per controllare i criteri di durata per l'istanza.

(Ereditato da MarshalByRefObject)
GetType()

Ottiene l'oggetto Type dell'istanza corrente.

(Ereditato da Object)
InitializeLifetimeService()
Obsoleti.

Ottiene un oggetto servizio di durata per controllare i criteri di durata per questa istanza.

(Ereditato da MarshalByRefObject)
MemberwiseClone()

Crea una copia superficiale dell'oggetto Object corrente.

(Ereditato da Object)
MemberwiseClone(Boolean)

Crea una copia dei riferimenti dell'oggetto MarshalByRefObject corrente.

(Ereditato da MarshalByRefObject)
SignalAndWait(WaitHandle, WaitHandle)

Segnala un oggetto WaitHandle e resta in attesa in un altro.

SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)

Segnala un oggetto WaitHandle e resta in attesa in un altro, specificando un intervallo di timeout come intero con segno a 32 bit e indicando se uscire dal dominio di sincronizzazione per il contesto prima dell'attesa.

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

Segnala un oggetto WaitHandle e resta in attesa di un altro, specificando l'intervallo di timeout come TimeSpan e indicando se uscire dal dominio di sincronizzazione per il contesto prima dell'attesa.

ToString()

Restituisce una stringa che rappresenta l'oggetto corrente.

(Ereditato da Object)
WaitAll(WaitHandle[])

Attende che tutti gli elementi nella matrice specificata ricevano un segnale.

WaitAll(WaitHandle[], Int32)

Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore Int32 per specificare l'intervallo di tempo.

WaitAll(WaitHandle[], Int32, Boolean)

Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore Int32 per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

WaitAll(WaitHandle[], TimeSpan)

Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo.

WaitAll(WaitHandle[], TimeSpan, Boolean)

Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

WaitAny(WaitHandle[])

Attende che uno degli elementi nella matrice specificata riceva un segnale.

WaitAny(WaitHandle[], Int32)

Attende che uno degli elementi nella matrice specificata riceva un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo.

WaitAny(WaitHandle[], Int32, Boolean)

Attende che uno degli elementi nella matrice specificata riceva un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

WaitAny(WaitHandle[], TimeSpan)

Attende che uno degli elementi nella matrice specificata riceva un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo.

WaitAny(WaitHandle[], TimeSpan, Boolean)

Attende che uno degli elementi nella matrice specificata riceva un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

WaitOne()

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale.

WaitOne(Int32)

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo.

WaitOne(Int32, Boolean)

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

WaitOne(TimeSpan)

Blocca il thread corrente finché l'istanza corrente non riceve un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo.

WaitOne(TimeSpan, Boolean)

Blocca il thread corrente finché l'istanza corrente non riceve un segnale, usando un oggetto TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

Implementazioni dell'interfaccia esplicita

IDisposable.Dispose()

Questa API supporta l'infrastruttura del prodotto e non è previsto che venga usata direttamente dal codice.

Rilascia tutte le risorse usate da WaitHandle.

Metodi di estensione

GetSafeWaitHandle(WaitHandle)

Ottiene l'handle sicuro per un handle di attesa nativo del sistema operativo.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Imposta un handle sicuro per un handle di attesa nativo del sistema operativo.

Si applica a

Thread safety

Questo tipo è thread-safe.

Vedi anche