WaitHandle.SignalAndWait Método

Definição

Sinaliza um WaitHandle e espera por outro.

Sobrecargas

Nome Description
SignalAndWait(WaitHandle, WaitHandle)

Sinaliza um WaitHandle e espera por outro.

SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)

Sinaliza um WaitHandle e aguarda em outro, especificando um intervalo de tempo limite como um inteiro com sinal de 32 bits e especificando se deseja sair do domínio de sincronização para o contexto antes de entrar na espera.

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

Sinaliza um WaitHandle e aguarda em outro, especificando o intervalo de tempo limite como um TimeSpan e especificando se deseja sair do domínio de sincronização para o contexto antes de entrar na espera.

SignalAndWait(WaitHandle, WaitHandle)

Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs

Sinaliza um WaitHandle e espera por 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 sinal de sinal.

toWaitOn
WaitHandle

O WaitHandle que esperar.

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 retornará.

Exceções

toSignal é null.

- ou -

toWaitOn é null.

O método foi chamado em um thread no STA estado.

toSignal é um semáforo e já tem uma contagem completa.

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 principal sinalize um thread bloqueado e aguarde até que o thread conclua 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. O exemplo, em seguida, enfileira outros cinco threads e libera todos eles usando um EventWaitHandle criado com o EventResetMode.ManualReset sinalizador.

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

Esta operação não tem garantia de ser atômica. Depois que o thread atual sinaliza toSignal , mas antes de aguardar toWaitOn, um thread em execução em outro processador pode sinalizar toWaitOn ou aguardar.

Aplica-se a

SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)

Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs

Sinaliza um WaitHandle e aguarda em outro, especificando um intervalo de tempo limite como um inteiro com sinal de 32 bits e especificando se deseja sair do domínio de sincronização para o contexto antes de entrar na 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 sinal de sinal.

toWaitOn
WaitHandle

O WaitHandle que esperar.

millisecondsTimeout
Int32

Um inteiro que representa o intervalo a ser esperado. Se o valor for Infinite, ou seja, -1, a espera será infinita.

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 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

toSignal é null.

- ou -

toWaitOn é null.

O método é chamado em um thread no STA estado.

O WaitHandle não pode ser sinalizado porque 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

Esta operação não tem garantia de ser atômica. Depois que o thread atual sinaliza toSignal , mas antes de aguardar toWaitOn, um thread em execução em outro processador pode sinalizar toWaitOn ou aguardar.

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 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

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs
Origem:
WaitHandle.cs

Sinaliza um WaitHandle e aguarda em outro, especificando o intervalo de tempo limite como um TimeSpan e especificando se deseja sair do domínio de sincronização para o contexto antes de entrar na 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 sinal de sinal.

toWaitOn
WaitHandle

O WaitHandle que esperar.

timeout
TimeSpan

Um TimeSpan que representa o intervalo a ser esperado. Se o valor for -1, a espera será infinita.

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 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

toSignal é null.

- ou -

toWaitOn é null.

O método foi chamado em um thread no STA estado.

toSignal é um semáforo e já tem uma contagem completa.

timeout avalia um número negativo de milissegundos diferentes de -1.

- ou -

timeout é maior que Int32.MaxValue.

A espera foi concluída porque um thread foi encerrado sem liberar um mutex.

Comentários

Esta operação não tem garantia de ser atômica. Depois que o thread atual sinaliza toSignal , mas antes de aguardar toWaitOn, um thread em execução em outro processador pode sinalizar toWaitOn ou aguardar.

O valor máximo é timeoutInt32.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 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