WaitHandle.WaitOne Método
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
Bloqueia o thread atual até que o atual WaitHandle receba um sinal.
Sobrecargas
| Nome | Description |
|---|---|
| WaitOne() |
Bloqueia o thread atual até que o atual WaitHandle receba um sinal. |
| WaitOne(Int32) |
Bloqueia o thread atual até que o atual WaitHandle receba um sinal, usando um inteiro com sinal 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 um TimeSpan para especificar o intervalo de tempo. |
| WaitOne(Int32, Boolean) |
Bloqueia o thread atual até que o atual WaitHandle receba um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo e especificando se o domínio de sincronização deve ser encerrado antes da espera. |
| 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 especificando se o domínio de sincronização deve ser encerrado antes da espera. |
WaitOne()
Bloqueia o thread atual até que o atual 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
Retornos
true se a instância atual receber um sinal. Se a instância atual nunca for sinalizada, WaitOne() nunca retornará.
Exceções
A instância atual já foi descartada.
A espera foi concluída porque um thread foi encerrado sem liberar um mutex.
A instância atual é um proxy transparente para um WaitHandle em outro domínio de aplicativo.
Exemplos
O exemplo de código a seguir mostra como usar um identificador de espera para impedir que um processo seja encerrado enquanto aguarda a conclusão da execução de um thread em segundo plano.
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
Comentários
AbandonedMutexException é novo no .NET Framework versão 2.0. Nas versões anteriores, o WaitOne método retorna true quando um mutex é abandonado. Um mutex abandonado geralmente indica um erro de codificação grave. No caso de um mutex em todo o sistema, pode indicar que um aplicativo foi encerrado abruptamente (por exemplo, usando o Gerenciador de Tarefas do Windows). A exceção contém informações úteis para depuração.
O chamador desse método bloqueia indefinidamente até que a instância atual receba um sinal. Use esse método para bloquear até que um WaitHandle sinal 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 essa sobrecarga de método é equivalente a chamar a sobrecarga do WaitOne(Int32, Boolean) método e especificar -1 ou Timeout.Infinite para o primeiro parâmetro e false para o segundo parâmetro.
Substitua esse método para personalizar o comportamento de classes derivadas.
Aplica-se a
WaitOne(Int32)
Bloqueia o thread atual até que o atual WaitHandle receba um sinal, usando um inteiro com sinal 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 a aguardar ou Infinite (-1) aguardar indefinidamente.
Retornos
true se a instância atual receber um sinal; caso contrário, false.
Exceções
A instância atual já foi descartada.
millisecondsTimeout é um número negativo diferente de -1, que representa um tempo limite infinito.
A espera foi concluída porque um thread foi encerrado sem liberar um mutex.
A instância atual é um proxy transparente para um WaitHandle em outro domínio de aplicativo.
Exemplos
O exemplo de código a seguir mostra como usar um identificador de espera para impedir que um processo seja encerrado enquanto aguarda a conclusão da execução de um thread em segundo plano.
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
Comentários
Se millisecondsTimeout for zero, o método não bloqueará. Ele testa o estado do identificador de espera e retorna imediatamente.
O chamador desse método bloqueia até que a instância atual receba um sinal ou um tempo limite ocorra. Use esse método para bloquear até que um WaitHandle sinal 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 esse método para personalizar o comportamento de classes derivadas.
Chamar essa sobrecarga de método é o mesmo que chamar a WaitOne(Int32, Boolean) sobrecarga e especificar false para exitContext.
Aplica-se a
WaitOne(TimeSpan)
Bloqueia o thread atual até que a instância atual receba um sinal, usando um 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
Um TimeSpan que representa o número de milissegundos a aguardar ou um TimeSpan que representa -1 milissegundos para aguardar indefinidamente.
Retornos
true se a instância atual receber um sinal; caso contrário, false.
Exceções
A instância atual já foi descartada.
timeout é um número negativo diferente de -1 milissegundos, que representa um tempo limite infinito.
-ou-
timeout é maior que Int32.MaxValue.
A espera foi concluída porque um thread foi encerrado sem liberar um mutex.
A instância atual é um proxy transparente para um WaitHandle em outro domínio de aplicativo.
Comentários
Se timeout for zero, o método não bloqueará. Ele testa o estado do identificador de espera e retorna imediatamente.
O chamador desse método bloqueia até que a instância atual receba um sinal ou um tempo limite ocorra. Use esse método para bloquear até que um WaitHandle sinal 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 esse método para personalizar o comportamento de classes derivadas.
O valor máximo é timeoutInt32.MaxValue.
Chamar essa sobrecarga de método é o mesmo que chamar a WaitOne(TimeSpan, Boolean) sobrecarga e especificar false para exitContext.
Aplica-se a
WaitOne(Int32, Boolean)
Bloqueia o thread atual até que o atual WaitHandle receba um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo e especificando se o domínio de sincronização deve ser encerrado 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 a aguardar ou Infinite (-1) aguardar indefinidamente.
- exitContext
- Boolean
true para sair do domínio de sincronização para o contexto antes da espera (se em um contexto sincronizado) e requisioná-lo posteriormente; caso contrário, false.
Retornos
true se a instância atual receber um sinal; caso contrário, false.
Exceções
A instância atual já foi descartada.
millisecondsTimeout é um número negativo diferente de -1, que representa um tempo limite infinito.
A espera foi concluída porque um thread foi encerrado sem liberar um mutex.
A instância atual é um proxy transparente para um WaitHandle em outro domínio de aplicativo.
Exemplos
O exemplo a seguir mostra como a sobrecarga do WaitOne(Int32, Boolean) método se comporta quando é chamada dentro de um domínio de sincronização. Primeiro, um thread aguarda com exitContext set to false e bloqueia até que o tempo limite de espera expire. Um segundo thread é executado após o término do primeiro thread e aguarda com exitContext definido como true. A chamada para sinalizar o identificador de espera para este segundo thread não está bloqueada e o thread é concluído antes do tempo limite 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!!!
Comentários
Se millisecondsTimeout for zero, o método não bloqueará. Ele testa o estado do identificador de espera e retorna imediatamente.
Se um mutex for abandonado, um AbandonedMutexException será lançado. Um mutex abandonado geralmente indica um erro de codificação grave. No caso de um mutex em todo o sistema, pode indicar que um aplicativo foi encerrado abruptamente (por exemplo, usando o Gerenciador de Tarefas do Windows). A exceção contém informações úteis para depuração.
O chamador desse método bloqueia até que a instância atual receba um sinal ou um tempo limite ocorra. Use esse método para bloquear até que um WaitHandle sinal 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 esse método para personalizar o comportamento de classes derivadas.
Saindo do contexto
O exitContext parâmetro não tem efeito, a menos que esse método seja chamado de dentro de um contexto gerenciado não padrão. O contexto gerenciado poderá ser não padrão se o thread estiver dentro de uma chamada para uma instância de uma classe derivada de ContextBoundObject. Mesmo que você esteja executando um método em uma classe que não seja derivada de ContextBoundObject, por exemplo String, você poderá estar em um contexto não padrão se estiver ContextBoundObject em sua pilha no domínio do aplicativo atual.
Quando o código está sendo executado em um contexto não padrão, especificar true para exitContext fazer com que o thread saia do contexto gerenciado não padrão (ou seja, fazer a transição para o contexto padrão) antes de executar esse método. O thread retorna ao contexto não padrão original após a conclusão da chamada para esse método.
Sair do contexto pode ser útil quando a classe associada 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 do código da classe. Se o código na pilha de chamadas de um membro chamar esse método e especificar trueexitContext, o thread sairá do domínio de sincronização, o que permite que um thread bloqueado em uma chamada para qualquer membro do objeto prossiga. Quando esse método retorna, o thread que fez a chamada deve aguardar para recuar novamente 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 um TimeSpan para especificar o intervalo de tempo e especificando se o domínio de sincronização deve ser encerrado 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
Um TimeSpan que representa o número de milissegundos a aguardar ou um TimeSpan que representa -1 milissegundos para aguardar indefinidamente.
- exitContext
- Boolean
true para sair do domínio de sincronização para o contexto antes da espera (se em um contexto sincronizado) e requisioná-lo posteriormente; caso contrário, false.
Retornos
true se a instância atual receber um sinal; caso contrário, false.
Exceções
A instância atual já foi descartada.
timeout é um número negativo diferente de -1 milissegundos, que representa um tempo limite infinito.
-ou-
timeout é maior que Int32.MaxValue.
A espera foi concluída porque um thread foi encerrado sem liberar um mutex.
A instância atual é um proxy transparente para um WaitHandle em outro domínio de aplicativo.
Exemplos
O exemplo de código a seguir mostra como usar um identificador de espera para impedir que um processo seja encerrado enquanto aguarda a conclusão da execução de um thread em segundo plano.
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
Comentários
Se timeout for zero, o método não bloqueará. Ele testa o estado do identificador de espera e retorna imediatamente.
Se um mutex for abandonado, um AbandonedMutexException será lançado. Um mutex abandonado geralmente indica um erro de codificação grave. No caso de um mutex em todo o sistema, pode indicar que um aplicativo foi encerrado abruptamente (por exemplo, usando o Gerenciador de Tarefas do Windows). A exceção contém informações úteis para depuração.
O chamador desse método bloqueia até que a instância atual receba um sinal ou um tempo limite ocorra. Use esse método para bloquear até que um WaitHandle sinal 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 esse método para personalizar o comportamento de classes derivadas.
O valor máximo é timeoutInt32.MaxValue.
Saindo do contexto
O exitContext parâmetro não tem efeito, a menos que esse método seja chamado de dentro de um contexto gerenciado não padrão. O contexto gerenciado poderá ser não padrão se o thread estiver dentro de uma chamada para uma instância de uma classe derivada de ContextBoundObject. Mesmo que você esteja executando um método em uma classe que não seja derivada de ContextBoundObject, por exemplo String, você poderá estar em um contexto não padrão se estiver ContextBoundObject em sua pilha no domínio do aplicativo atual.
Quando o código está sendo executado em um contexto não padrão, especificar true para exitContext fazer com que o thread saia do contexto gerenciado não padrão (ou seja, fazer a transição para o contexto padrão) antes de executar esse método. O thread retorna ao contexto não padrão original após a conclusão da chamada para esse método.
Sair do contexto pode ser útil quando a classe associada 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 do código da classe. Se o código na pilha de chamadas de um membro chamar esse método e especificar trueexitContext, o thread sairá do domínio de sincronização, o que permite que um thread bloqueado em uma chamada para qualquer membro do objeto prossiga. Quando esse método retorna, o thread que fez a chamada deve aguardar para recuar novamente no domínio de sincronização.