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 WaitHandle atual receba um sinal.
Sobrecargas
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(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 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, 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. |
WaitOne()
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
Bloqueia o thread atual até que o WaitHandle atual 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 será retornado.
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 namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
WaitOne(){}
public:
static void WorkMethod( Object^ stateInfo )
{
Console::WriteLine( "Work starting." );
// Simulate time spent working.
Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
// Signal that work is finished.
Console::WriteLine( "Work ending." );
dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
}
};
int main()
{
Console::WriteLine( "Main starting." );
AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::WorkMethod ), autoEvent );
// Wait for work method to signal.
autoEvent->WaitOne( );
Console::WriteLine( "Work method signaled.\nMain ending." );
}
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. Em versões anteriores, o WaitOne método retorna true
quando um mutex é abandonado. Um mutex abandonado geralmente indica um erro grave de codificação. No caso de um mutex em todo o sistema, isso 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 é bloqueado indefinidamente até que a instância atual receba um sinal. Use esse método para bloquear até que um 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 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)
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
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.
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 aguardar ou Infinite (- 1) 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.
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 namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
WaitOne(){}
public:
static void WorkMethod( Object^ stateInfo )
{
Console::WriteLine( "Work starting." );
// Simulate time spent working.
Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
// Signal that work is finished.
Console::WriteLine( "Work ending." );
dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
}
};
int main()
{
Console::WriteLine( "Main starting." );
AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::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." );
}
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 é bloqueado até que a instância atual receba um sinal ou um tempo limite ocorra. Use esse método para bloquear até que um 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 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)
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
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 para 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 milissegundo, 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 é bloqueado até que a instância atual receba um sinal ou um tempo limite ocorra. Use esse método para bloquear até que um 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 esse método para personalizar o comportamento de classes derivadas.
O valor máximo para timeout
é Int32.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)
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
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.
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 aguardar ou Infinite (- 1) para aguardar indefinidamente.
- exitContext
- Boolean
true
para sair do domínio de sincronização do contexto antes do tempo de espera (se estiver em um contexto sincronizado) e readquiri-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 definido como exitContext
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 definido true
como exitContext
. A chamada para sinalizar o identificador de espera para esse segundo thread não está bloqueada e o thread é concluído antes do tempo limite de espera.
using namespace System;
using namespace System::Threading;
using namespace System::Runtime::Remoting::Contexts;
[Synchronization(true)]
public ref class SyncingClass : ContextBoundObject
{
private:
EventWaitHandle^ waitHandle;
public:
SyncingClass()
{
waitHandle =
gcnew EventWaitHandle(false, EventResetMode::ManualReset);
}
void Signal()
{
Console::WriteLine("Thread[{0:d4}]: Signalling...", Thread::CurrentThread->GetHashCode());
waitHandle->Set();
}
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 ref class TestSyncDomainWait
{
public:
static void Main()
{
SyncingClass^ syncClass = gcnew SyncingClass();
Thread^ runWaiter;
Console::WriteLine("\nWait and signal INSIDE synchronization domain:\n");
runWaiter = gcnew Thread(gcnew ParameterizedThreadStart(&TestSyncDomainWait::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 = gcnew Thread(gcnew ParameterizedThreadStart(&TestSyncDomainWait::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();
}
static void RunWaitKeepContext(Object^ parm)
{
((SyncingClass^)parm)->DoWait(false);
}
static void RunWaitLeaveContext(Object^ parm)
{
((SyncingClass^)parm)->DoWait(true);
}
};
int main()
{
TestSyncDomainWait::Main();
}
// 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!!!
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 grave de codificação. No caso de um mutex em todo o sistema, isso 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 é bloqueado até que a instância atual receba um sinal ou um tempo limite ocorra. Use esse método para bloquear até que um 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 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á não ser 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 é derivada de ContextBoundObject, como String, você pode estar em um contexto não padrão se um ContextBoundObject estiver em sua pilha no domínio do aplicativo atual.
Quando o código está em execução em um contexto não padrão, especificar true
para exitContext
faz 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 para a classe. Se o código na pilha de chamadas de um membro chamar esse método e especificar true
para exitContext
, o thread sairá do domínio de sincronização, o que permitirá que um thread bloqueado em uma chamada para qualquer membro do objeto continue. Quando esse método retorna, o thread que fez a chamada deve aguardar para inserir novamente o domínio de sincronização.
Aplica-se a
WaitOne(TimeSpan, Boolean)
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
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.
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 para aguardar ou um TimeSpan que representa -1 milissegundos para aguardar indefinidamente.
- exitContext
- Boolean
true
para sair do domínio de sincronização do contexto antes do tempo de espera (se estiver em um contexto sincronizado) e readquiri-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 milissegundo, 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 namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
WaitOne(){}
public:
static void WorkMethod( Object^ stateInfo )
{
Console::WriteLine( "Work starting." );
// Simulate time spent working.
Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
// Signal that work is finished.
Console::WriteLine( "Work ending." );
dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
}
};
int main()
{
Console::WriteLine( "Main starting." );
AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::WorkMethod ), autoEvent );
// Wait for work method to signal.
if ( autoEvent->WaitOne( 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." );
}
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á gerado. Um mutex abandonado geralmente indica um erro grave de codificação. 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 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 para timeout
é Int32.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 é derivada de ContextBoundObject, como String, você pode estar em um contexto não padrão se um ContextBoundObject estiver 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
faz 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 para a classe . Se o código na pilha de chamadas de um membro chamar esse método e especificar true
para exitContext
, o thread sairá do domínio de sincronização, o que permitirá 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 reentrada no domínio de sincronização.