WaitHandle.WaitOne Método
Definição
Importante
Algumas informações dizem respeito a um produto pré-lançado que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.
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.