WaitHandle Classe

Définition

Encapsule des objets spécifiques au système d'exploitation, qui attendent un accès exclusif aux ressources partagées.

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
Héritage
WaitHandle
Héritage
Dérivé
Attributs
Implémente

Exemples

L’exemple de code suivant montre comment deux threads peuvent effectuer des tâches en arrière-plan pendant que le thread principal attend que les tâches se terminent à l’aide des WaitAny méthodes et statiques WaitAll de la 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 tasks are 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).

Remarques

La WaitHandle classe encapsule un handle de synchronisation du système d’exploitation natif et est utilisé pour représenter tous les objets de synchronisation dans le runtime qui autorisent plusieurs opérations d’attente. Pour une comparaison des handles d’attente avec d’autres objets de synchronisation, consultez vue d’ensemble des primitives de synchronisation.

La WaitHandle classe elle-même est abstraite. Les classes dérivées de WaitHandle définissent un mécanisme de signalisation pour indiquer la capture ou la libération de l’accès à une ressource partagée, mais elles utilisent les méthodes héritées WaitHandle pour bloquer tout en attendant l’accès aux ressources partagées. Les classes dérivées de WaitHandle sont les suivantes :

Les threads peuvent se bloquer sur un handle d’attente individuel en appelant la méthode d’instance WaitOne , qui est héritée par les classes dérivées de WaitHandle .

Les classes dérivées de WaitHandle diffèrent dans leur affinité de thread. Les handles d’attente d’événement ( EventWaitHandle , AutoResetEvent et ManualResetEvent ) et les sémaphores n’ont pas d’affinité de thread ; tout thread peut signaler un sémaphore ou un descripteur d’attente d’événement. En revanche, les mutex ont une affinité de thread ; le thread qui possède un mutex doit le libérer, et une exception est levée si un thread appelle la ReleaseMutex méthode sur un mutex qu’il ne possède pas.

Étant donné que la WaitHandle classe dérive de MarshalByRefObject , ces classes peuvent être utilisées pour synchroniser les activités des threads au-delà des limites du domaine d’application.

En plus de ses classes dérivées, la WaitHandle classe a plusieurs méthodes statiques qui bloquent un thread jusqu’à ce qu’un ou plusieurs objets de synchronisation reçoivent un signal. Elles incluent notamment :

  • SignalAndWait, qui permet à un thread de signaler un handle d’attente et d’attendre immédiatement un autre.

  • WaitAll, qui permet à un thread d’attendre que tous les handles d’attente d’un tableau reçoivent un signal.

  • WaitAny, qui permet à un thread d’attendre jusqu’à ce que l’un des jeux de handles d’attente spécifiés ait été signalé.

Les surcharges de ces méthodes fournissent des intervalles de délai d’attente pour abandonner l’attente, et la possibilité de quitter un contexte de synchronisation avant d’entrer dans l’attente, ce qui permet à d’autres threads d’utiliser le contexte de synchronisation.

Important

Ce type implémente l'interface IDisposable. Lorsque vous avez fini d’utiliser le type ou un type dérivé de celui-ci, vous devez le supprimer directement ou indirectement. Pour supprimer directement le type Close, appelez sa méthode dans un bloc try/catch. Pour la supprimer indirectement, utilisez une construction de langage telle que using (dans C#) ou Using (dans Visual Basic). Pour plus d’informations, consultez la section « Utilisation d’un objet qui implémente IDisposable » dans la rubrique de l’interface IDisposable.

WaitHandle implémente le Dispose modèle. Consultez implémentation d’une méthode dispose. Quand vous dérivez de WaitHandle , utilisez la SafeWaitHandle propriété pour stocker votre handle de système d’exploitation natif. Vous n’avez pas besoin de substituer la Dispose méthode protégée, sauf si vous utilisez des ressources non managées supplémentaires.

Constructeurs

WaitHandle()

Initialise une nouvelle instance de la classe WaitHandle.

Champs

InvalidHandle

Représente un handle du système d'exploitation natif non valide. Ce champ est en lecture seule.

WaitTimeout

Indique que le délai fixé pour une opération WaitAny(WaitHandle[], Int32, Boolean) a été dépassé sans qu'aucun des handles d'attente n'ait été signalé. Ce champ est constant.

Propriétés

Handle
Obsolète.
Obsolète.

Obtient ou définit le handle du système d'exploitation natif.

SafeWaitHandle

Obtient ou définit le handle du système d'exploitation natif.

Méthodes

Close()

Libère toutes les ressources détenues par le WaitHandle actuel.

CreateObjRef(Type)

Crée un objet contenant toutes les informations appropriées requises pour générer un proxy permettant de communiquer avec un objet distant.

(Hérité de MarshalByRefObject)
Dispose()

Libère toutes les ressources utilisées par l'instance actuelle de la classe WaitHandle.

Dispose(Boolean)

En cas de substitution dans une classe dérivée, libère les ressources non managées utilisées par WaitHandle et libère éventuellement les ressources managées.

Equals(Object)

Détermine si l'objet spécifié est égal à l'objet actuel.

(Hérité de Object)
Finalize()

Libère les ressources détenues par l’instance actuelle.

GetHashCode()

Fait office de fonction de hachage par défaut.

(Hérité de Object)
GetLifetimeService()
Obsolète.

Récupère l'objet de service de durée de vie en cours qui contrôle la stratégie de durée de vie de cette instance.

(Hérité de MarshalByRefObject)
GetType()

Obtient le Type de l'instance actuelle.

(Hérité de Object)
InitializeLifetimeService()
Obsolète.

Obtient un objet de service de durée de vie pour contrôler la stratégie de durée de vie de cette instance.

(Hérité de MarshalByRefObject)
MemberwiseClone()

Crée une copie superficielle du Object actuel.

(Hérité de Object)
MemberwiseClone(Boolean)

Crée une copie superficielle de l'objet MarshalByRefObject actuel.

(Hérité de MarshalByRefObject)
SignalAndWait(WaitHandle, WaitHandle)

Signale un WaitHandle et attend un autre.

SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)

Signale un WaitHandle et en attend un autre, en spécifiant un délai sous la forme d'un entier signé 32 bits et en spécifiant s'il faut quitter le domaine de synchronisation du contexte avant de commencer l'attente.

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

Signale un WaitHandle et en attend un autre, en spécifiant le délai sous la forme d’une valeur TimeSpan et en spécifiant s’il faut quitter le domaine de synchronisation du contexte avant de commencer l’attente.

ToString()

Retourne une chaîne qui représente l'objet actuel.

(Hérité de Object)
WaitAll(WaitHandle[])

Attend que tous les éléments du tableau spécifié reçoivent un signal.

WaitAll(WaitHandle[], Int32)

Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur Int32 pour spécifier l'intervalle de temps.

WaitAll(WaitHandle[], Int32, Boolean)

Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur Int32 pour spécifier l'intervalle de temps et en spécifiant s'il faut quitter le domaine de synchronisation avant l'attente.

WaitAll(WaitHandle[], TimeSpan)

Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps.

WaitAll(WaitHandle[], TimeSpan, Boolean)

Attend que tous les éléments du tableau spécifié reçoivent un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps et en spécifiant s'il faut quitter le domaine de synchronisation avant l'attente.

WaitAny(WaitHandle[])

Attend que l'un des éléments du tableau spécifié reçoive un signal.

WaitAny(WaitHandle[], Int32)

Attend que l'un des éléments du tableau spécifié reçoive un signal, en utilisant un entier signé 32 bits pour spécifier l'intervalle de temps.

WaitAny(WaitHandle[], Int32, Boolean)

Attend que l’un des éléments du tableau spécifié reçoive un signal, en utilisant un entier signé 32 bits pour spécifier l’intervalle de temps et en spécifiant s’il faut quitter le domaine de synchronisation avant l’attente.

WaitAny(WaitHandle[], TimeSpan)

Attend que l'un des éléments du tableau spécifié reçoive un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps.

WaitAny(WaitHandle[], TimeSpan, Boolean)

Attend que l’un des éléments du tableau spécifié reçoive un signal ; en utilisant une valeur TimeSpan pour spécifier l’intervalle de temps et en spécifiant s’il faut quitter le domaine de synchronisation avant l’attente.

WaitOne()

Bloque le thread actuel jusqu'à ce que le WaitHandle actuel reçoive un signal.

WaitOne(Int32)

Bloque le thread actuel jusqu'à ce que le WaitHandle actuel reçoive un signal, en utilisant un entier signé 32 bits pour spécifier l'intervalle de temps.

WaitOne(Int32, Boolean)

Bloque le thread actuel jusqu’à ce que le WaitHandle actuel reçoive un signal, en utilisant un entier signé 32 bits pour spécifier l’intervalle de temps et en spécifiant s’il faut quitter le domaine de synchronisation avant l’attente.

WaitOne(TimeSpan)

Bloque le thread actuel jusqu'à ce que l'instance actuelle reçoive un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps.

WaitOne(TimeSpan, Boolean)

Bloque le thread actuel jusqu'à ce que l'instance actuelle reçoive un signal, en utilisant une valeur TimeSpan pour spécifier l'intervalle de temps et en spécifiant s'il faut quitter le domaine de synchronisation avant l'attente.

Implémentations d’interfaces explicites

IDisposable.Dispose()

Cette API prend en charge l'infrastructure du produit et n'est pas destinée à être utilisée directement à partir de votre code.

Libère toutes les ressources utilisées par WaitHandle.

Méthodes d’extension

GetSafeWaitHandle(WaitHandle)

Obtient le handle sécurisé pour un handle d’attente de système d’exploitation natif.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Définit un handle sécurisé pour un handle d’attente de système d’exploitation natif.

S’applique à

Cohérence de thread

Ce type est thread-safe.

Voir aussi