WaitHandle.WaitOne Método

Definição

Bloqueia a linha de corrente até que a corrente WaitHandle receba um sinal.

Sobrecargas

Name Description
WaitOne()

Bloqueia a linha de corrente até que a corrente WaitHandle receba um sinal.

WaitOne(Int32)

Bloqueia a thread da corrente até que a corrente WaitHandle receba um sinal, usando um inteiro assinado de 32 bits para especificar o intervalo de tempo em milissegundos.

WaitOne(TimeSpan)

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

WaitOne(Int32, Boolean)

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

WaitOne(TimeSpan, Boolean)

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

WaitOne()

Bloqueia a linha de corrente até que a corrente WaitHandle receba um sinal.

public:
 virtual bool WaitOne();
public virtual bool WaitOne();
abstract member WaitOne : unit -> bool
override this.WaitOne : unit -> bool
Public Overridable Function WaitOne () As Boolean

Devoluções

true se a instância atual receber um sinal. Se a instância atual nunca for sinalizada, WaitOne() nunca regressa.

Exceções

O caso atual já foi resolvido.

A espera terminou porque um tópico saiu sem divulgar um mutex.

A instância atual é um proxy transparente para um WaitHandle noutro domínio de aplicação.

Exemplos

O exemplo de código seguinte mostra como usar uma alça de espera para impedir que um processo termine enquanto espera que um thread em segundo plano termine a execução.

using System;
using System.Threading;

class WaitOne
{
    static AutoResetEvent autoEvent = new AutoResetEvent(false);

    static void Main()
    {
        Console.WriteLine("Main starting.");

        ThreadPool.QueueUserWorkItem(
            new WaitCallback(WorkMethod), autoEvent);

        // Wait for work method to signal.
        autoEvent.WaitOne();
        Console.WriteLine("Work method signaled.\nMain ending.");
    }

    static void WorkMethod(object stateInfo) 
    {
        Console.WriteLine("Work starting.");

        // Simulate time spent working.
        Thread.Sleep(new Random().Next(100, 2000));

        // Signal that work is finished.
        Console.WriteLine("Work ending.");
        ((AutoResetEvent)stateInfo).Set();
    }
}
Imports System.Threading

Public Class WaitOne

    Shared autoEvent As New AutoResetEvent(False)

    <MTAThread> _
    Shared Sub Main()
        Console.WriteLine("Main starting.")

        ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, autoEvent)

        ' Wait for work method to signal.
        autoEvent.WaitOne()
        Console.WriteLine("Work method signaled.")
        Console.WriteLine("Main ending.")
    End Sub

    Shared Sub WorkMethod(stateInfo As Object) 
        Console.WriteLine("Work starting.")

        ' Simulate time spent working.
        Thread.Sleep(New Random().Next(100, 2000))

        ' Signal that work is finished.
        Console.WriteLine("Work ending.")
        CType(stateInfo, AutoResetEvent).Set()
    End Sub

End Class

Observações

AbandonedMutexException é novo na versão 2.0 do .NET Framework. Em versões anteriores, o WaitOne método retorna true quando um mutex é abandonado. Um mutex abandonado indica frequentemente um erro grave de codificação. No caso de um mutex em todo o sistema, pode indicar que uma aplicação foi terminada abruptamente (por exemplo, usando o Gestor de Tarefas do Windows). A exceção contém informações úteis para depuração.

O chamador deste método bloqueia indefinidamente até que a instância atual receba um sinal. Use este método para bloquear até que a WaitHandle receba um sinal de outro thread, como é gerado quando uma operação assíncrona é concluída. Para obter mais informações, consulte a IAsyncResult interface.

Chamar este método de sobrecarga é equivalente a chamar o WaitOne(Int32, Boolean) método de sobrecarga e especificar -1 ou Timeout.Infinite para o primeiro parâmetro e false para o segundo parâmetro.

Substitua este método para personalizar o comportamento das classes derivadas.

Aplica-se a

WaitOne(Int32)

Bloqueia a thread da corrente até que a corrente WaitHandle receba um sinal, usando um inteiro assinado de 32 bits para especificar o intervalo de tempo em milissegundos.

public:
 virtual bool WaitOne(int millisecondsTimeout);
public virtual bool WaitOne(int millisecondsTimeout);
abstract member WaitOne : int -> bool
override this.WaitOne : int -> bool
Public Overridable Function WaitOne (millisecondsTimeout As Integer) As Boolean

Parâmetros

millisecondsTimeout
Int32

O número de milissegundos para esperar, ou Infinite (-1) para esperar indefinidamente.

Devoluções

true se a instância atual receber um sinal; caso contrário, false.

Exceções

O caso atual já foi resolvido.

millisecondsTimeout é um número negativo diferente de -1, o que representa um tempo limite infinito.

A espera terminou porque um tópico saiu sem divulgar um mutex.

A instância atual é um proxy transparente para um WaitHandle noutro domínio de aplicação.

Exemplos

O exemplo de código seguinte mostra como usar uma alça de espera para impedir que um processo termine enquanto espera que um thread em segundo plano termine a execução.

using System;
using System.Threading;

class WaitOne
{
    static AutoResetEvent autoEvent = new AutoResetEvent(false);

    static void Main()
    {
        Console.WriteLine("Main starting.");

        ThreadPool.QueueUserWorkItem(
            new WaitCallback(WorkMethod), autoEvent);

        // Wait for work method to signal.
        if(autoEvent.WaitOne(1000))
        {
            Console.WriteLine("Work method signaled.");
        }
        else
        {
            Console.WriteLine("Timed out waiting for work " +
                "method to signal.");
        }
        Console.WriteLine("Main ending.");
    }

    static void WorkMethod(object stateInfo) 
    {
        Console.WriteLine("Work starting.");

        // Simulate time spent working.
        Thread.Sleep(new Random().Next(100, 2000));

        // Signal that work is finished.
        Console.WriteLine("Work ending.");
        ((AutoResetEvent)stateInfo).Set();
    }
}
Imports System.Threading

Public Class WaitOne

    Shared autoEvent As New AutoResetEvent(False)

    <MTAThread> _
    Shared Sub Main()
        Console.WriteLine("Main starting.")

        ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, autoEvent)

        ' Wait for work method to signal.
        If autoEvent.WaitOne(1000) Then
            Console.WriteLine("Work method signaled.")
        Else
            Console.WriteLine("Timed out waiting for work " & _
                "method to signal.")
        End If

        Console.WriteLine("Main ending.")
    End Sub

    Shared Sub WorkMethod(stateInfo As Object) 
        Console.WriteLine("Work starting.")

        ' Simulate time spent working.
        Thread.Sleep(New Random().Next(100, 2000))

        ' Signal that work is finished.
        Console.WriteLine("Work ending.")
        CType(stateInfo, AutoResetEvent).Set()
    End Sub

End Class

Observações

Se millisecondsTimeout for zero, o método não bloqueia. Testa o estado da alavanca de espera e retorna imediatamente.

O chamador deste método bloqueia até que a instância atual receba um sinal ou ocorra um time-out. Use este método para bloquear até que a WaitHandle receba um sinal de outro thread, como é gerado quando uma operação assíncrona é concluída. Para obter mais informações, consulte a IAsyncResult interface.

Substitua este método para personalizar o comportamento das classes derivadas.

Chamar a este método overload é o mesmo que chamar a WaitOne(Int32, Boolean) overload e especificar false para exitContext.

Aplica-se a

WaitOne(TimeSpan)

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

public:
 virtual bool WaitOne(TimeSpan timeout);
public virtual bool WaitOne(TimeSpan timeout);
abstract member WaitOne : TimeSpan -> bool
override this.WaitOne : TimeSpan -> bool
Public Overridable Function WaitOne (timeout As TimeSpan) As Boolean

Parâmetros

timeout
TimeSpan

A TimeSpan que representa o número de milissegundos para esperar, ou a TimeSpan que representa -1 milissegundos para esperar indefinidamente.

Devoluções

true se a instância atual receber um sinal; caso contrário, false.

Exceções

O caso atual já foi resolvido.

timeout é um número negativo diferente de -1 milissegundos, o que representa um tempo de espera infinito.

-ou-

timeout é maior do que Int32.MaxValue.

A espera terminou porque um tópico saiu sem divulgar um mutex.

A instância atual é um proxy transparente para um WaitHandle noutro domínio de aplicação.

Observações

Se timeout for zero, o método não bloqueia. Testa o estado da alavanca de espera e retorna imediatamente.

O chamador deste método bloqueia até que a instância atual receba um sinal ou ocorra um time-out. Use este método para bloquear até que a WaitHandle receba um sinal de outro thread, como é gerado quando uma operação assíncrona é concluída. Para obter mais informações, consulte a IAsyncResult interface.

Substitua este método para personalizar o comportamento das classes derivadas.

O valor máximo para timeout é Int32.MaxValue.

Chamar a este método overload é o mesmo que chamar a WaitOne(TimeSpan, Boolean) overload e especificar false para exitContext.

Aplica-se a

WaitOne(Int32, Boolean)

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

public:
 virtual bool WaitOne(int millisecondsTimeout, bool exitContext);
public virtual bool WaitOne(int millisecondsTimeout, bool exitContext);
abstract member WaitOne : int * bool -> bool
override this.WaitOne : int * bool -> bool
Public Overridable Function WaitOne (millisecondsTimeout As Integer, exitContext As Boolean) As Boolean

Parâmetros

millisecondsTimeout
Int32

O número de milissegundos para esperar, ou Infinite (-1) para esperar indefinidamente.

exitContext
Boolean

true sair do domínio de sincronização do contexto antes da espera (se estiver num contexto sincronizado), e readquiri-lo depois; caso contrário, false.

Devoluções

true se a instância atual receber um sinal; caso contrário, false.

Exceções

O caso atual já foi resolvido.

millisecondsTimeout é um número negativo diferente de -1, o que representa um tempo limite infinito.

A espera terminou porque um tópico saiu sem divulgar um mutex.

A instância atual é um proxy transparente para um WaitHandle noutro domínio de aplicação.

Exemplos

O exemplo seguinte mostra como a WaitOne(Int32, Boolean) sobrecarga do método se comporta quando é chamada dentro de um domínio de sincronização. Primeiro, um thread espera com exitContext definido como false e bloqueia até o tempo de espera expirar. Um segundo thread executa-se após o término do primeiro thread e espera com exitContext definido como true. A chamada para sinalizar o handler de espera deste segundo thread não é bloqueada, e o thread termina antes do tempo de espera.

using System;
using System.Threading;
using System.Runtime.Remoting.Contexts;

[Synchronization(true)]
public class SyncingClass : ContextBoundObject
{
    private EventWaitHandle waitHandle;

    public SyncingClass()
    {
         waitHandle =
            new EventWaitHandle(false, EventResetMode.ManualReset);
    }

    public void Signal()
    {
        Console.WriteLine("Thread[{0:d4}]: Signalling...", Thread.CurrentThread.GetHashCode());
        waitHandle.Set();
    }

    public void DoWait(bool leaveContext)
    {
        bool signalled;

        waitHandle.Reset();
        Console.WriteLine("Thread[{0:d4}]: Waiting...", Thread.CurrentThread.GetHashCode());
        signalled = waitHandle.WaitOne(3000, leaveContext);
        if (signalled)
        {
            Console.WriteLine("Thread[{0:d4}]: Wait released!!!", Thread.CurrentThread.GetHashCode());
        }
        else
        {
            Console.WriteLine("Thread[{0:d4}]: Wait timeout!!!", Thread.CurrentThread.GetHashCode());
        }
    }
}

public class TestSyncDomainWait
{
    public static void Main()
    {
        SyncingClass syncClass = new SyncingClass();

        Thread runWaiter;

        Console.WriteLine("\nWait and signal INSIDE synchronization domain:\n");
        runWaiter = new Thread(RunWaitKeepContext);
        runWaiter.Start(syncClass);
        Thread.Sleep(1000);
        Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode());
        // This call to Signal will block until the timeout in DoWait expires.
        syncClass.Signal();
        runWaiter.Join();

        Console.WriteLine("\nWait and signal OUTSIDE synchronization domain:\n");
        runWaiter = new Thread(RunWaitLeaveContext);
        runWaiter.Start(syncClass);
        Thread.Sleep(1000);
        Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode());
        // This call to Signal is unblocked and will set the wait handle to
        // release the waiting thread.
        syncClass.Signal();
        runWaiter.Join();
    }

    public static void RunWaitKeepContext(object parm)
    {
        ((SyncingClass)parm).DoWait(false);
    }

    public static void RunWaitLeaveContext(object parm)
    {
        ((SyncingClass)parm).DoWait(true);
    }
}

// The output for the example program will be similar to the following:
//
// Wait and signal INSIDE synchronization domain:
//
// Thread[0004]: Waiting...
// Thread[0001]: Signal...
// Thread[0004]: Wait timeout!!!
// Thread[0001]: Signalling...
//
// Wait and signal OUTSIDE synchronization domain:
//
// Thread[0006]: Waiting...
// Thread[0001]: Signal...
// Thread[0001]: Signalling...
// Thread[0006]: Wait released!!!
Imports System.Threading
Imports System.Runtime.Remoting.Contexts

<Synchronization(true)>
Public Class SyncingClass
    Inherits ContextBoundObject
    
    Private waitHandle As EventWaitHandle

    Public Sub New()
         waitHandle = New EventWaitHandle(false, EventResetMode.ManualReset)
    End Sub

    Public Sub Signal()
        Console.WriteLine("Thread[{0:d4}]: Signalling...", Thread.CurrentThread.GetHashCode())
        waitHandle.Set()
    End Sub

    Public Sub DoWait(leaveContext As Boolean)
        Dim signalled As Boolean

        waitHandle.Reset()
        Console.WriteLine("Thread[{0:d4}]: Waiting...", Thread.CurrentThread.GetHashCode())
        signalled = waitHandle.WaitOne(3000, leaveContext)
        If signalled Then
            Console.WriteLine("Thread[{0:d4}]: Wait released!!!", Thread.CurrentThread.GetHashCode())
        Else
            Console.WriteLine("Thread[{0:d4}]: Wait timeout!!!", Thread.CurrentThread.GetHashCode())
        End If
    End Sub
End Class

Public Class TestSyncDomainWait
    Public Shared Sub Main()
        Dim syncClass As New SyncingClass()

        Dim runWaiter As Thread

        Console.WriteLine(Environment.NewLine + "Wait and signal INSIDE synchronization domain:" + Environment.NewLine)
        runWaiter = New Thread(AddressOf RunWaitKeepContext)
        runWaiter.Start(syncClass)
        Thread.Sleep(1000)
        Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode())
        ' This call to Signal will block until the timeout in DoWait expires.
        syncClass.Signal()
        runWaiter.Join()

        Console.WriteLine(Environment.NewLine + "Wait and signal OUTSIDE synchronization domain:" + Environment.NewLine)
        runWaiter = New Thread(AddressOf RunWaitLeaveContext)
        runWaiter.Start(syncClass)
        Thread.Sleep(1000)
        Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode())
        ' This call to Signal is unblocked and will set the wait handle to
        ' release the waiting thread.
        syncClass.Signal()
        runWaiter.Join()
    End Sub

    Public Shared Sub RunWaitKeepContext(parm As Object)
        Dim syncClass As SyncingClass = CType(parm, SyncingClass)
        syncClass.DoWait(False)
    End Sub

    Public Shared Sub RunWaitLeaveContext(parm As Object)
        Dim syncClass As SyncingClass = CType(parm, SyncingClass)
        syncClass.DoWait(True)
    End Sub
End Class

' The output for the example program will be similar to the following:
'
' Wait and signal INSIDE synchronization domain:
'
' Thread[0004]: Waiting...
' Thread[0001]: Signal...
' Thread[0004]: Wait timeout!!!
' Thread[0001]: Signalling...
'
' Wait and signal OUTSIDE synchronization domain:
'
' Thread[0006]: Waiting...
' Thread[0001]: Signal...
' Thread[0001]: Signalling...
' Thread[0006]: Wait released!!!

Observações

Se millisecondsTimeout for zero, o método não bloqueia. Testa o estado da alavanca de espera e retorna imediatamente.

Se um mutex for abandonado, um AbandonedMutexException é lançado. Um mutex abandonado indica frequentemente um erro grave de codificação. No caso de um mutex em todo o sistema, pode indicar que uma aplicação foi terminada abruptamente (por exemplo, usando o Gestor de Tarefas do Windows). A exceção contém informações úteis para depuração.

O chamador deste método bloqueia até que a instância atual receba um sinal ou ocorra um time-out. Use este método para bloquear até que a WaitHandle receba um sinal de outro thread, como é gerado quando uma operação assíncrona é concluída. Para obter mais informações, consulte a IAsyncResult interface.

Substitua este método para personalizar o comportamento das classes derivadas.

Saindo do contexto

O exitContext parâmetro não tem efeito a menos que este método seja chamado dentro de um contexto gerido não predefinido. O contexto gerido pode ser não padrão se o seu thread estiver dentro de uma chamada para uma instância de uma classe derivada de ContextBoundObject. Mesmo que esteja atualmente a executar um método numa classe que não deriva de ContextBoundObject, como String, pode estar num contexto não padrão se a ContextBoundObject estiver na sua pilha no domínio de aplicação atual.

Quando o seu código está a ser executado num contexto não padrão, especificar true para exitContext faz com que o thread saia do contexto gerido não padrão (isto é, para transitar para o contexto padrão) antes de executar este método. O thread regressa ao contexto original não padrão após a conclusão da chamada a este método.

Sair do contexto pode ser útil quando a classe ligada ao contexto tem o SynchronizationAttribute atributo. Nesse caso, todas as chamadas para membros da classe são sincronizadas automaticamente e o domínio de sincronização é todo o corpo de código da classe. Se o código na pilha de chamadas de um membro chamar este método e especificar true para exitContext, o thread sai do domínio de sincronização, o que permite que um thread bloqueado numa chamada para qualquer membro do objeto prossiga. Quando este método regressa, o thread que fez a chamada tem de esperar para reentrar no domínio de sincronização.

Aplica-se a

WaitOne(TimeSpan, Boolean)

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

public:
 virtual bool WaitOne(TimeSpan timeout, bool exitContext);
public virtual bool WaitOne(TimeSpan timeout, bool exitContext);
abstract member WaitOne : TimeSpan * bool -> bool
override this.WaitOne : TimeSpan * bool -> bool
Public Overridable Function WaitOne (timeout As TimeSpan, exitContext As Boolean) As Boolean

Parâmetros

timeout
TimeSpan

A TimeSpan que representa o número de milissegundos para esperar, ou a TimeSpan que representa -1 milissegundos para esperar indefinidamente.

exitContext
Boolean

true sair do domínio de sincronização do contexto antes da espera (se estiver num contexto sincronizado), e readquiri-lo depois; caso contrário, false.

Devoluções

true se a instância atual receber um sinal; caso contrário, false.

Exceções

O caso atual já foi resolvido.

timeout é um número negativo diferente de -1 milissegundos, o que representa um tempo de espera infinito.

-ou-

timeout é maior do que Int32.MaxValue.

A espera terminou porque um tópico saiu sem divulgar um mutex.

A instância atual é um proxy transparente para um WaitHandle noutro domínio de aplicação.

Exemplos

O exemplo de código seguinte mostra como usar uma alça de espera para impedir que um processo termine enquanto espera que um thread em segundo plano termine a execução.

using System;
using System.Threading;

class WaitOne
{
    static AutoResetEvent autoEvent = new AutoResetEvent(false);

    static void Main()
    {
        Console.WriteLine("Main starting.");

        ThreadPool.QueueUserWorkItem(
            new WaitCallback(WorkMethod), autoEvent);

        // Wait for work method to signal.
        if(autoEvent.WaitOne(new TimeSpan(0, 0, 1), false))
        {
            Console.WriteLine("Work method signaled.");
        }
        else
        {
            Console.WriteLine("Timed out waiting for work " +
                "method to signal.");
        }
        Console.WriteLine("Main ending.");
    }

    static void WorkMethod(object stateInfo) 
    {
        Console.WriteLine("Work starting.");

        // Simulate time spent working.
        Thread.Sleep(new Random().Next(100, 2000));

        // Signal that work is finished.
        Console.WriteLine("Work ending.");
        ((AutoResetEvent)stateInfo).Set();
    }
}
Imports System.Threading

Public Class WaitOne

    Shared autoEvent As New AutoResetEvent(False)

    <MTAThread> _
    Shared Sub Main()
        Console.WriteLine("Main starting.")

        ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, autoEvent)

        ' Wait for work method to signal.
        If autoEvent.WaitOne(New TimeSpan(0, 0, 1), False) Then
            Console.WriteLine("Work method signaled.")
        Else
            Console.WriteLine("Timed out waiting for work " & _
                "method to signal.")
        End If

        Console.WriteLine("Main ending.")
    End Sub

    Shared Sub WorkMethod(stateInfo As Object) 
        Console.WriteLine("Work starting.")

        ' Simulate time spent working.
        Thread.Sleep(New Random().Next(100, 2000))

        ' Signal that work is finished.
        Console.WriteLine("Work ending.")
        CType(stateInfo, AutoResetEvent).Set()
    End Sub

End Class

Observações

Se timeout for zero, o método não bloqueia. Testa o estado da alavanca de espera e retorna imediatamente.

Se um mutex for abandonado, um AbandonedMutexException é lançado. Um mutex abandonado indica frequentemente um erro grave de codificação. No caso de um mutex em todo o sistema, pode indicar que uma aplicação foi terminada abruptamente (por exemplo, usando o Gestor de Tarefas do Windows). A exceção contém informações úteis para depuração.

O chamador deste método bloqueia até que a instância atual receba um sinal ou ocorra um time-out. Use este método para bloquear até que a WaitHandle receba um sinal de outro thread, como é gerado quando uma operação assíncrona é concluída. Para obter mais informações, consulte a IAsyncResult interface.

Substitua este método para personalizar o comportamento das classes derivadas.

O valor máximo para timeout é Int32.MaxValue.

Saindo do contexto

O exitContext parâmetro não tem efeito a menos que este método seja chamado dentro de um contexto gerido não predefinido. O contexto gerido pode ser não padrão se o seu thread estiver dentro de uma chamada para uma instância de uma classe derivada de ContextBoundObject. Mesmo que esteja atualmente a executar um método numa classe que não deriva de ContextBoundObject, como String, pode estar num contexto não padrão se a ContextBoundObject estiver na sua pilha no domínio de aplicação atual.

Quando o seu código está a ser executado num contexto não padrão, especificar true para exitContext faz com que o thread saia do contexto gerido não padrão (isto é, para transitar para o contexto padrão) antes de executar este método. O thread regressa ao contexto original não padrão após a conclusão da chamada a este método.

Sair do contexto pode ser útil quando a classe ligada ao contexto tem o SynchronizationAttribute atributo. Nesse caso, todas as chamadas para membros da classe são sincronizadas automaticamente e o domínio de sincronização é todo o corpo de código da classe. Se o código na pilha de chamadas de um membro chamar este método e especificar true para exitContext, o thread sai do domínio de sincronização, o que permite que um thread bloqueado numa chamada para qualquer membro do objeto prossiga. Quando este método regressa, o thread que fez a chamada tem de esperar para reentrar no domínio de sincronização.

Aplica-se a