WaitHandle.SignalAndWait 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.
Sinaliza uma WaitHandle e espera em outro.
Sobrecargas
SignalAndWait(WaitHandle, WaitHandle) |
Sinaliza uma WaitHandle e espera em outro. |
SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean) |
Sinaliza um WaitHandle e espera outro, especificando um intervalo de tempo limite como um inteiro com sinal de 32 bits e especificando se é necessário sair do domínio de sincronização do contexto antes de entrar em espera. |
SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean) |
Sinaliza um WaitHandle e espera outro, especificando um intervalo de tempo limite como um TimeSpan e especificando se é necessário sair do domínio de sincronização do contexto antes de entrar em espera. |
SignalAndWait(WaitHandle, WaitHandle)
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
Sinaliza uma WaitHandle e espera em outro.
public:
static bool SignalAndWait(System::Threading::WaitHandle ^ toSignal, System::Threading::WaitHandle ^ toWaitOn);
public static bool SignalAndWait (System.Threading.WaitHandle toSignal, System.Threading.WaitHandle toWaitOn);
static member SignalAndWait : System.Threading.WaitHandle * System.Threading.WaitHandle -> bool
Public Shared Function SignalAndWait (toSignal As WaitHandle, toWaitOn As WaitHandle) As Boolean
Parâmetros
- toSignal
- WaitHandle
O WaitHandle para sinalizar.
- toWaitOn
- WaitHandle
O WaitHandle a ser esperado.
Retornos
true
se o sinal e a espera forem concluídos com êxito. Se a espera não for concluída, o método não será retornado.
Exceções
O método foi chamado em um thread no estado STA.
toSignal
é um semáforo e já tem uma contagem total.
A espera foi concluída porque um thread foi encerrado sem liberar um mutex.
Exemplos
O exemplo de código a seguir usa a sobrecarga do SignalAndWait(WaitHandle, WaitHandle) método para permitir que o thread main sinalize um thread bloqueado e aguarde até que o thread termine uma tarefa.
O exemplo inicia cinco threads, permite que eles bloqueiem em um EventWaitHandle criado com o EventResetMode.AutoReset sinalizador e, em seguida, libera um thread cada vez que o usuário pressiona a tecla ENTER. Em seguida, o exemplo enfileira outros cinco threads e libera todos eles usando um EventWaitHandle criado com o EventResetMode.ManualReset sinalizador .
using namespace System;
using namespace System::Threading;
public ref class Example
{
private:
// The EventWaitHandle used to demonstrate the difference
// between AutoReset and ManualReset synchronization events.
//
static EventWaitHandle^ ewh;
// A counter to make sure all threads are started and
// blocked before any are released. A Long is used to show
// the use of the 64-bit Interlocked methods.
//
static __int64 threadCount = 0;
// An AutoReset event that allows the main thread to block
// until an exiting thread has decremented the count.
//
static EventWaitHandle^ clearCount =
gcnew EventWaitHandle( false,EventResetMode::AutoReset );
public:
[MTAThread]
static void main()
{
// Create an AutoReset EventWaitHandle.
//
ewh = gcnew EventWaitHandle( false,EventResetMode::AutoReset );
// Create and start five numbered threads. Use the
// ParameterizedThreadStart delegate, so the thread
// number can be passed as an argument to the Start
// method.
for ( int i = 0; i <= 4; i++ )
{
Thread^ t = gcnew Thread(
gcnew ParameterizedThreadStart( ThreadProc ) );
t->Start( i );
}
// Wait until all the threads have started and blocked.
// When multiple threads use a 64-bit value on a 32-bit
// system, you must access the value through the
// Interlocked class to guarantee thread safety.
//
while ( Interlocked::Read( threadCount ) < 5 )
{
Thread::Sleep( 500 );
}
// Release one thread each time the user presses ENTER,
// until all threads have been released.
//
while ( Interlocked::Read( threadCount ) > 0 )
{
Console::WriteLine( L"Press ENTER to release a waiting thread." );
Console::ReadLine();
// SignalAndWait signals the EventWaitHandle, which
// releases exactly one thread before resetting,
// because it was created with AutoReset mode.
// SignalAndWait then blocks on clearCount, to
// allow the signaled thread to decrement the count
// before looping again.
//
WaitHandle::SignalAndWait( ewh, clearCount );
}
Console::WriteLine();
// Create a ManualReset EventWaitHandle.
//
ewh = gcnew EventWaitHandle( false,EventResetMode::ManualReset );
// Create and start five more numbered threads.
//
for ( int i = 0; i <= 4; i++ )
{
Thread^ t = gcnew Thread(
gcnew ParameterizedThreadStart( ThreadProc ) );
t->Start( i );
}
// Wait until all the threads have started and blocked.
//
while ( Interlocked::Read( threadCount ) < 5 )
{
Thread::Sleep( 500 );
}
// Because the EventWaitHandle was created with
// ManualReset mode, signaling it releases all the
// waiting threads.
//
Console::WriteLine( L"Press ENTER to release the waiting threads." );
Console::ReadLine();
ewh->Set();
}
static void ThreadProc( Object^ data )
{
int index = static_cast<Int32>(data);
Console::WriteLine( L"Thread {0} blocks.", data );
// Increment the count of blocked threads.
Interlocked::Increment( threadCount );
// Wait on the EventWaitHandle.
ewh->WaitOne();
Console::WriteLine( L"Thread {0} exits.", data );
// Decrement the count of blocked threads.
Interlocked::Decrement( threadCount );
// After signaling ewh, the main thread blocks on
// clearCount until the signaled thread has
// decremented the count. Signal it now.
//
clearCount->Set();
}
};
using System;
using System.Threading;
public class Example
{
// The EventWaitHandle used to demonstrate the difference
// between AutoReset and ManualReset synchronization events.
//
private static EventWaitHandle ewh;
// A counter to make sure all threads are started and
// blocked before any are released. A Long is used to show
// the use of the 64-bit Interlocked methods.
//
private static long threadCount = 0;
// An AutoReset event that allows the main thread to block
// until an exiting thread has decremented the count.
//
private static EventWaitHandle clearCount =
new EventWaitHandle(false, EventResetMode.AutoReset);
[MTAThread]
public static void Main()
{
// Create an AutoReset EventWaitHandle.
//
ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
// Create and start five numbered threads. Use the
// ParameterizedThreadStart delegate, so the thread
// number can be passed as an argument to the Start
// method.
for (int i = 0; i <= 4; i++)
{
Thread t = new Thread(
new ParameterizedThreadStart(ThreadProc)
);
t.Start(i);
}
// Wait until all the threads have started and blocked.
// When multiple threads use a 64-bit value on a 32-bit
// system, you must access the value through the
// Interlocked class to guarantee thread safety.
//
while (Interlocked.Read(ref threadCount) < 5)
{
Thread.Sleep(500);
}
// Release one thread each time the user presses ENTER,
// until all threads have been released.
//
while (Interlocked.Read(ref threadCount) > 0)
{
Console.WriteLine("Press ENTER to release a waiting thread.");
Console.ReadLine();
// SignalAndWait signals the EventWaitHandle, which
// releases exactly one thread before resetting,
// because it was created with AutoReset mode.
// SignalAndWait then blocks on clearCount, to
// allow the signaled thread to decrement the count
// before looping again.
//
WaitHandle.SignalAndWait(ewh, clearCount);
}
Console.WriteLine();
// Create a ManualReset EventWaitHandle.
//
ewh = new EventWaitHandle(false, EventResetMode.ManualReset);
// Create and start five more numbered threads.
//
for(int i=0; i<=4; i++)
{
Thread t = new Thread(
new ParameterizedThreadStart(ThreadProc)
);
t.Start(i);
}
// Wait until all the threads have started and blocked.
//
while (Interlocked.Read(ref threadCount) < 5)
{
Thread.Sleep(500);
}
// Because the EventWaitHandle was created with
// ManualReset mode, signaling it releases all the
// waiting threads.
//
Console.WriteLine("Press ENTER to release the waiting threads.");
Console.ReadLine();
ewh.Set();
}
public static void ThreadProc(object data)
{
int index = (int) data;
Console.WriteLine("Thread {0} blocks.", data);
// Increment the count of blocked threads.
Interlocked.Increment(ref threadCount);
// Wait on the EventWaitHandle.
ewh.WaitOne();
Console.WriteLine("Thread {0} exits.", data);
// Decrement the count of blocked threads.
Interlocked.Decrement(ref threadCount);
// After signaling ewh, the main thread blocks on
// clearCount until the signaled thread has
// decremented the count. Signal it now.
//
clearCount.Set();
}
}
Imports System.Threading
Public Class Example
' The EventWaitHandle used to demonstrate the difference
' between AutoReset and ManualReset synchronization events.
'
Private Shared ewh As EventWaitHandle
' A counter to make sure all threads are started and
' blocked before any are released. A Long is used to show
' the use of the 64-bit Interlocked methods.
'
Private Shared threadCount As Long = 0
' An AutoReset event that allows the main thread to block
' until an exiting thread has decremented the count.
'
Private Shared clearCount As New EventWaitHandle(False, _
EventResetMode.AutoReset)
<MTAThread> _
Public Shared Sub Main()
' Create an AutoReset EventWaitHandle.
'
ewh = New EventWaitHandle(False, EventResetMode.AutoReset)
' Create and start five numbered threads. Use the
' ParameterizedThreadStart delegate, so the thread
' number can be passed as an argument to the Start
' method.
For i As Integer = 0 To 4
Dim t As New Thread(AddressOf ThreadProc)
t.Start(i)
Next i
' Wait until all the threads have started and blocked.
' When multiple threads use a 64-bit value on a 32-bit
' system, you must access the value through the
' Interlocked class to guarantee thread safety.
'
While Interlocked.Read(threadCount) < 5
Thread.Sleep(500)
End While
' Release one thread each time the user presses ENTER,
' until all threads have been released.
'
While Interlocked.Read(threadCount) > 0
Console.WriteLine("Press ENTER to release a waiting thread.")
Console.ReadLine()
' SignalAndWait signals the EventWaitHandle, which
' releases exactly one thread before resetting,
' because it was created with AutoReset mode.
' SignalAndWait then blocks on clearCount, to
' allow the signaled thread to decrement the count
' before looping again.
'
WaitHandle.SignalAndWait(ewh, clearCount)
End While
Console.WriteLine()
' Create a ManualReset EventWaitHandle.
'
ewh = New EventWaitHandle(False, EventResetMode.ManualReset)
' Create and start five more numbered threads.
'
For i As Integer = 0 To 4
Dim t As New Thread(AddressOf ThreadProc)
t.Start(i)
Next i
' Wait until all the threads have started and blocked.
'
While Interlocked.Read(threadCount) < 5
Thread.Sleep(500)
End While
' Because the EventWaitHandle was created with
' ManualReset mode, signaling it releases all the
' waiting threads.
'
Console.WriteLine("Press ENTER to release the waiting threads.")
Console.ReadLine()
ewh.Set()
End Sub
Public Shared Sub ThreadProc(ByVal data As Object)
Dim index As Integer = CInt(data)
Console.WriteLine("Thread {0} blocks.", data)
' Increment the count of blocked threads.
Interlocked.Increment(threadCount)
' Wait on the EventWaitHandle.
ewh.WaitOne()
Console.WriteLine("Thread {0} exits.", data)
' Decrement the count of blocked threads.
Interlocked.Decrement(threadCount)
' After signaling ewh, the main thread blocks on
' clearCount until the signaled thread has
' decremented the count. Signal it now.
'
clearCount.Set()
End Sub
End Class
Comentários
Não há garantia de que essa operação seja atômica. Depois que o thread atual sinaliza toSignal
, mas antes de aguardar , toWaitOn
um thread que está em execução em outro processador pode sinalizar toWaitOn
ou esperar por ele.
Aplica-se a
SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
Sinaliza um WaitHandle e espera outro, especificando um intervalo de tempo limite como um inteiro com sinal de 32 bits e especificando se é necessário sair do domínio de sincronização do contexto antes de entrar em espera.
public:
static bool SignalAndWait(System::Threading::WaitHandle ^ toSignal, System::Threading::WaitHandle ^ toWaitOn, int millisecondsTimeout, bool exitContext);
public static bool SignalAndWait (System.Threading.WaitHandle toSignal, System.Threading.WaitHandle toWaitOn, int millisecondsTimeout, bool exitContext);
static member SignalAndWait : System.Threading.WaitHandle * System.Threading.WaitHandle * int * bool -> bool
Public Shared Function SignalAndWait (toSignal As WaitHandle, toWaitOn As WaitHandle, millisecondsTimeout As Integer, exitContext As Boolean) As Boolean
Parâmetros
- toSignal
- WaitHandle
O WaitHandle para sinalizar.
- toWaitOn
- WaitHandle
O WaitHandle a ser esperado.
- millisecondsTimeout
- Int32
Um inteiro que representa o intervalo de espera. Se o valor for Infinite, ou seja, -1, a espera será infinita.
- 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 o sinal e a espera foram concluídos com êxito ou false
se o sinal foi concluído, mas a espera atingiu o tempo limite.
Exceções
O método é chamado em um thread no estado STA.
O WaitHandle não pode ser sinalizado porque isso excederia sua contagem máxima.
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.
Comentários
Não há garantia de que essa operação seja atômica. Depois que o thread atual sinaliza toSignal
, mas antes de aguardar , toWaitOn
um thread que está em execução em outro processador pode sinalizar toWaitOn
ou esperar por ele.
Se millisecondsTimeout
for zero, o método não bloqueará. Ele testa o estado do toWaitOn
e retorna imediatamente.
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.
Aplica-se a
SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
Sinaliza um WaitHandle e espera outro, especificando um intervalo de tempo limite como um TimeSpan e especificando se é necessário sair do domínio de sincronização do contexto antes de entrar em espera.
public:
static bool SignalAndWait(System::Threading::WaitHandle ^ toSignal, System::Threading::WaitHandle ^ toWaitOn, TimeSpan timeout, bool exitContext);
public static bool SignalAndWait (System.Threading.WaitHandle toSignal, System.Threading.WaitHandle toWaitOn, TimeSpan timeout, bool exitContext);
static member SignalAndWait : System.Threading.WaitHandle * System.Threading.WaitHandle * TimeSpan * bool -> bool
Public Shared Function SignalAndWait (toSignal As WaitHandle, toWaitOn As WaitHandle, timeout As TimeSpan, exitContext As Boolean) As Boolean
Parâmetros
- toSignal
- WaitHandle
O WaitHandle para sinalizar.
- toWaitOn
- WaitHandle
O WaitHandle a ser esperado.
- timeout
- TimeSpan
Um TimeSpan que representa o intervalo de espera. Se o valor for -1, a espera será infinita.
- 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 o sinal e a espera foram concluídos com êxito ou false
se o sinal foi concluído, mas a espera atingiu o tempo limite.
Exceções
O método foi chamado em um thread no estado STA.
toSignal
é um semáforo e já tem uma contagem total.
timeout
é avaliado como um número negativo de milissegundos diferente de -1.
- ou -
timeout
é maior que Int32.MaxValue.
A espera foi concluída porque um thread foi encerrado sem liberar um mutex.
Comentários
Não há garantia de que essa operação seja atômica. Depois que o thread atual sinaliza toSignal
, mas antes de aguardar , toWaitOn
um thread que está em execução em outro processador pode sinalizar toWaitOn
ou esperar por ele.
O valor máximo para timeout
é Int32.MaxValue.
Se timeout
for zero, o método não bloqueará. Ele testa o estado do toWaitOn
e retorna imediatamente.
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.