WaitHandle Classe

Definição

Encapsula objetos específicos do sistema operacional que aguardam acesso exclusivo aos recursos compartilhados.

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
Herança
WaitHandle
Herança
Derivado
Atributos
Implementações

Exemplos

O exemplo de código a seguir mostra como dois threads podem realizar tarefas em segundo plano enquanto o thread Principal aguarda a conclusão das tarefas usando os métodos e WaitAll estáticos WaitAny da 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).

Comentários

A WaitHandle classe encapsula um identificador de sincronização do sistema operacional nativo e é usada para representar todos os objetos de sincronização no runtime que permitem várias operações de espera. Para obter uma comparação de identificadores de espera com outros objetos de sincronização, consulte Visão geral dos primitivos de sincronização.

A WaitHandle classe em si é abstrata. Classes derivadas de definem um mecanismo de WaitHandle sinalização para indicar a tomada ou liberação de acesso a um recurso compartilhado, mas usam os métodos herdados WaitHandle para bloquear enquanto aguardam o acesso aos recursos compartilhados. As classes derivadas de WaitHandle incluem:

Os threads podem bloquear em um identificador de espera individual chamando o método WaitOnede instância , que é herdado por classes derivadas de WaitHandle.

As classes derivadas de WaitHandle diferem em sua afinidade de thread. Os identificadores de espera de eventos (EventWaitHandle, AutoResetEvente ManualResetEvent) e semáforos não têm afinidade de thread; qualquer thread pode sinalizar um identificador de espera de evento ou semáforo. Os mutexes, por outro lado, têm afinidade de thread; o thread que possui um mutex deve liberá-lo e uma exceção será gerada se um thread chamar o ReleaseMutex método em um mutex que ele não possui.

Como a WaitHandle classe deriva de MarshalByRefObject, essas classes podem ser usadas para sincronizar as atividades dos threads entre os limites do domínio do aplicativo.

Além de suas classes derivadas, a WaitHandle classe tem vários métodos estáticos que bloqueiam um thread até que um ou mais objetos de sincronização recebam um sinal. Elas incluem:

  • SignalAndWait, que permite que um thread sinalize um identificador de espera e aguarde imediatamente em outro.

  • WaitAll, que permite que um thread aguarde até que todos os identificadores de espera em uma matriz recebam um sinal.

  • WaitAny, que permite que um thread aguarde até que qualquer um de um conjunto especificado de identificadores de espera tenha sido sinalizado.

As sobrecargas desses métodos fornecem intervalos de tempo limite para abandonar a espera e a oportunidade de sair de um contexto de sincronização antes de entrar na espera, permitindo que outros threads usem o contexto de sincronização.

Importante

Esse tipo implementa a interface IDisposable. Quando terminar de usar o tipo ou um tipo derivado dele, você deverá descartá-lo direta ou indiretamente. Para descartar o tipo diretamente, chame o método Close dele em um bloco try/catch. Para descartá-lo indiretamente, use um constructo de linguagem como using ( em C#) ou Using (em Visual Basic). Saiba mais na seção "Como usar um objeto que implementa IDisposable" no tópico da interface IDisposable.

WaitHandle implementa o Dispose padrão. Consulte Implementando um método Dispose. Quando você derivar de WaitHandle, use a propriedade para armazenar o SafeWaitHandle identificador do sistema operacional nativo. Você não precisa substituir o método protegido Dispose , a menos que use recursos não gerenciados adicionais.

Construtores

WaitHandle()

Inicializa uma nova instância da classe WaitHandle.

Campos

InvalidHandle

Representa um identificador de sistema operacional nativo inválido. Este campo é somente leitura.

WaitTimeout

Indica que uma operação WaitAny(WaitHandle[], Int32, Boolean) atingiu o tempo limite antes que algum dos identificadores de espera fosse sinalizado. Este campo é constante.

Propriedades

Handle
Obsoleto.
Obsoleto.

Obtém ou define o identificador de sistema operacional nativo.

SafeWaitHandle

Obtém ou define o identificador de sistema operacional nativo.

Métodos

Close()

Libera todos os recursos mantidos pelo WaitHandle atual.

CreateObjRef(Type)

Cria um objeto que contém todas as informações relevantes necessárias para gerar um proxy usado para se comunicar com um objeto remoto.

(Herdado de MarshalByRefObject)
Dispose()

Libera todos os recursos usados pela instância atual da classe WaitHandle.

Dispose(Boolean)

Quando substituído em uma classe derivada, libera os recursos não gerenciados usados pelo WaitHandle e, opcionalmente, libera os recursos gerenciados.

Equals(Object)

Determina se o objeto especificado é igual ao objeto atual.

(Herdado de Object)
Finalize()

Libera os recursos mantidos pela instância atual.

GetHashCode()

Serve como a função de hash padrão.

(Herdado de Object)
GetLifetimeService()
Obsoleto.

Recupera o objeto de serviço de tempo de vida atual que controla a política de ciclo de vida para esta instância.

(Herdado de MarshalByRefObject)
GetType()

Obtém o Type da instância atual.

(Herdado de Object)
InitializeLifetimeService()
Obsoleto.

Obtém um objeto de serviço de tempo de vida para controlar a política de tempo de vida para essa instância.

(Herdado de MarshalByRefObject)
MemberwiseClone()

Cria uma cópia superficial do Object atual.

(Herdado de Object)
MemberwiseClone(Boolean)

Cria uma cópia superficial do objeto MarshalByRefObject atual.

(Herdado de MarshalByRefObject)
SignalAndWait(WaitHandle, WaitHandle)

Sinaliza uma WaitHandle e espera em outro.

SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)

Sinaliza um WaitHandle e espera outro, especificando um intervalo de tempo limite como um inteiro com sinal de 32 bits e especificando se é necessário sair do domínio de sincronização do contexto antes de entrar em espera.

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

Sinaliza um WaitHandle e espera outro, especificando um intervalo de tempo limite como um TimeSpan e especificando se é necessário sair do domínio de sincronização do contexto antes de entrar em espera.

ToString()

Retorna uma cadeia de caracteres que representa o objeto atual.

(Herdado de Object)
WaitAll(WaitHandle[])

Aguarda até que todos os elementos na matriz especificada recebam um sinal.

WaitAll(WaitHandle[], Int32)

Espera que todos os elementos na matriz especificada recebam um sinal usando um valor Int32 para especificar o intervalo de tempo.

WaitAll(WaitHandle[], Int32, Boolean)

Espera todos os elementos da matriz especificada receberem um sinal, usando um valor Int32 para especificar o intervalo de tempo e especificar se deseja sair do domínio de sincronização antes do tempo de espera.

WaitAll(WaitHandle[], TimeSpan)

Espera que todos os elementos na matriz especificada recebam um sinal usando um valor TimeSpan para especificar o intervalo de tempo.

WaitAll(WaitHandle[], TimeSpan, Boolean)

Aguarda até que todos os elementos da matriz especificada recebam um sinal, usando um valor TimeSpan para especificar o intervalo de tempo e especificando se sairá do domínio de sincronização antes da espera.

WaitAny(WaitHandle[])

Aguarda até que todos os elementos na matriz especificada recebam um sinal.

WaitAny(WaitHandle[], Int32)

Espera qualquer um dos elementos na matriz especificada receber um sinal usando um inteiro com sinal de 32 bits a fim de especificar o intervalo de tempo.

WaitAny(WaitHandle[], Int32, Boolean)

Espera todos os elementos na matriz especificada receberem um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo e especificar se deseja sair do domínio de sincronização antes do tempo de espera.

WaitAny(WaitHandle[], TimeSpan)

Aguarda até todos os elementos na matriz especificada receberem um sinal usando um TimeSpan para especificar o intervalo de tempo.

WaitAny(WaitHandle[], TimeSpan, Boolean)

Espera todos os elementos na matriz especificada receberem um sinal, usando um TimeSpan para especificar o intervalo de tempo e especificar se deseja sair do domínio de sincronização antes do tempo de espera.

WaitOne()

Bloqueia o thread atual até que o WaitHandle atual receba um sinal.

WaitOne(Int32)

Bloqueia o thread atual até que o WaitHandle atual receba um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo em milissegundos.

WaitOne(Int32, Boolean)

Bloqueia o thread atual até que o WaitHandle atual receba um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo e especificar se sairá do domínio de sincronização antes da espera.

WaitOne(TimeSpan)

Bloqueia o thread atual até que a instância atual receba um sinal, usando um TimeSpan para especificar o intervalo de tempo.

WaitOne(TimeSpan, Boolean)

Bloqueia o thread atual até que a instância atual receba um sinal, usando um TimeSpan para especificar o intervalo de tempo e especificar se sairá do domínio de sincronização antes da espera.

Implantações explícitas de interface

IDisposable.Dispose()

Esta API dá suporte à infraestrutura do produto e não deve ser usada diretamente do seu código.

Libera todos os recursos usados pelo WaitHandle.

Métodos de Extensão

GetSafeWaitHandle(WaitHandle)

Obtém o identificador seguro para um identificador de espera nativo do sistema operacional.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Define um identificador seguro para um identificador de espera do sistema operacional nativo.

Aplica-se a

Acesso thread-safe

Este tipo é thread-safe.

Confira também