WaitHandle.SignalAndWait Método

Definição

Sinaliza um WaitHandle e espera pelo outro.

Sobrecargas

Name Description
SignalAndWait(WaitHandle, WaitHandle)

Sinaliza um WaitHandle e espera pelo outro.

SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)

Sinaliza um WaitHandle e espera noutro, especificando um intervalo de tempo como um inteiro assinado de 32 bits e especificando se deve sair do domínio de sincronização para o contexto antes de entrar na espera.

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

Sinaliza um WaitHandle e espera noutro, especificando o intervalo de time-out como a TimeSpan e especificando se deve 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 pelo 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 para.

toWaitOn
WaitHandle

O WaitHandle para esperar.

Devoluções

true se tanto o sinal como a espera forem concluídos com sucesso; Se a espera não for concluída, o método não retorna.

Exceções

toSignal é null.

-ou-

toWaitOn é null.

O método era chamado num fio em STA estado.

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

A espera terminou porque um tópico saiu sem divulgar um mutex.

Exemplos

O exemplo de código seguinte usa o SignalAndWait(WaitHandle, WaitHandle) método overload para permitir que o thread principal sinalize um thread bloqueado e depois espere até que o thread termine uma tarefa.

O exemplo inicia cinco threads, permite-lhes bloquear num EventWaitHandle criado com a EventResetMode.AutoReset flag, e depois liberta um thread cada vez que o utilizador pressiona a tecla ENTER. O exemplo coloca então mais cinco threads e liberta-os todos usando um EventWaitHandle created with the EventResetMode.ManualReset flag.

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

Observações

Esta operação não é garantida que seja atómica. Depois de a thread atual sinalizar toSignal , mas antes de esperar , toWaitOnuma thread que está a correr noutro processador pode sinalizar toWaitOn ou esperar por ela.

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 espera noutro, especificando um intervalo de tempo como um inteiro assinado de 32 bits e especificando se deve 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 para.

toWaitOn
WaitHandle

O WaitHandle para esperar.

millisecondsTimeout
Int32

Um inteiro que representa o intervalo a esperar. Se o valor for Infinite, ou seja, -1, a espera é infinita.

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 tanto o sinal como a espera foram concluídos com sucesso, ou false se o sinal terminou mas o tempo de espera esgotou.

Exceções

toSignal é null.

-ou-

toWaitOn é null.

O método é chamado num fio no STA estado.

Não WaitHandle podem ser sinalizados porque excederiam o seu número máximo.

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.

Observações

Esta operação não é garantida que seja atómica. Depois de a thread atual sinalizar toSignal , mas antes de esperar , toWaitOnuma thread que está a correr noutro processador pode sinalizar toWaitOn ou esperar por ela.

Se millisecondsTimeout for zero, o método não bloqueia. Testa o estado do toWaitOn e retorna imediatamente.

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

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

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

Sinaliza um WaitHandle e espera noutro, especificando o intervalo de time-out como a TimeSpan e especificando se deve 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 para.

toWaitOn
WaitHandle

O WaitHandle para esperar.

timeout
TimeSpan

A TimeSpan que representa o intervalo de espera. Se o valor for -1, a espera é infinita.

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 tanto o sinal como a espera foram concluídos com sucesso, ou false se o sinal terminou mas o tempo de espera esgotou.

Exceções

toSignal é null.

-ou-

toWaitOn é null.

O método era chamado num fio em STA estado.

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

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

-ou-

timeout é maior do que Int32.MaxValue.

A espera terminou porque um tópico saiu sem divulgar um mutex.

Observações

Esta operação não é garantida que seja atómica. Depois de a thread atual sinalizar toSignal , mas antes de esperar , toWaitOnuma thread que está a correr noutro processador pode sinalizar toWaitOn ou esperar por ela.

O valor máximo para timeout é Int32.MaxValue.

Se timeout for zero, o método não bloqueia. Testa o estado do toWaitOn e retorna imediatamente.

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