WaitHandle.SignalAndWait 方法

定义

发出一个信号并等待另一 WaitHandle 个。

重载

名称 说明
SignalAndWait(WaitHandle, WaitHandle)

发出一个信号并等待另一 WaitHandle 个。

SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)

发出一个 WaitHandle 信号并等待另一个,将超时间隔指定为 32 位有符号整数,并指定是否在输入等待之前退出上下文的同步域。

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

发出信号并等待另一个 WaitHandle ,将超时间隔指定为 TimeSpan 超时间隔,并指定是否在输入等待之前退出上下文的同步域。

SignalAndWait(WaitHandle, WaitHandle)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

发出一个信号并等待另一 WaitHandle 个。

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

参数

toSignal
WaitHandle

WaitHandle 发出信号。

toWaitOn
WaitHandle

等待 WaitHandle

返回

true 如果信号和等待成功完成,则为如果等待未完成,则该方法不会返回。

例外

toSignalnull

-或-

toWaitOnnull

该方法在处于状态的 STA 线程上调用。

toSignal 是信号灯,并且已具有完整计数。

等待已完成,因为线程退出而不释放互斥体。

示例

下面的代码示例使用 SignalAndWait(WaitHandle, WaitHandle) 方法重载允许主线程向阻塞线程发出信号,然后等待线程完成任务。

该示例启动五个 EventWaitHandle 线程,允许它们阻止使用 EventResetMode.AutoReset 标志创建的线程,然后每次用户按下 Enter 键时释放一个线程。 然后,该示例再对五个线程进行排队,并使用标志EventWaitHandle创建的线程释放它们EventResetMode.ManualReset

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

注解

此操作不保证为原子操作。 在当前线程发出信号 toSignal 但等待 toWaitOn之前,在另一个处理器上运行的线程可能会发出信号 toWaitOn 或等待。

适用于

SignalAndWait(WaitHandle, WaitHandle, Int32, Boolean)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

发出一个 WaitHandle 信号并等待另一个,将超时间隔指定为 32 位有符号整数,并指定是否在输入等待之前退出上下文的同步域。

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

参数

toSignal
WaitHandle

WaitHandle 发出信号。

toWaitOn
WaitHandle

等待 WaitHandle

millisecondsTimeout
Int32

一个整数,表示要等待的间隔。 如果值为 Infinite-1,则等待是无限的。

exitContext
Boolean

true 如果处于同步上下文中,请在等待之前退出上下文的同步域(如果在同步的上下文中),然后重新获取它;否则,为 false.

返回

true 如果信号和等待都成功完成,或者 false 信号已完成,但等待超时。

例外

toSignalnull

-或-

toWaitOnnull

该方法在处于状态的 STA 线程上调用。

WaitHandle无法发出信号,因为它将超过其最大计数。

millisecondsTimeout 是非 -1 的负数,表示无限超时。

等待已完成,因为线程退出而不释放互斥体。

注解

此操作不保证为原子操作。 在当前线程发出信号 toSignal 但等待 toWaitOn之前,在另一个处理器上运行的线程可能会发出信号 toWaitOn 或等待。

如果 millisecondsTimeout 为零,则该方法不会阻止。 它会测试状态 toWaitOn 并立即返回。

退出上下文

除非从非默认托管上下文内部调用此方法,否则参数 exitContext 不起作用。 如果线程在对派生自 ContextBoundObject的类实例的调用中,则托管上下文可以是非默认上下文。 即使当前在未派生自 ContextBoundObject的类上执行方法,例如 String,如果在 ContextBoundObject 当前应用程序域中的堆栈上,也可以位于非默认上下文中。

当代码在非默认上下文中执行时,指定 trueexitContext 会导致线程在执行此方法之前退出非默认托管上下文(即转换到默认上下文)。 调用此方法后,线程将返回到原始非默认上下文。

当上下文绑定类具有 SynchronizationAttribute 属性时,退出上下文可能很有用。 在这种情况下,对类成员的所有调用都会自动同步,并且同步域是该类的整个代码正文。 如果成员调用堆栈中的代码调用此方法并指定 trueexitContext则线程将退出同步域,从而允许在调用对象的任何成员时阻止的线程继续。 此方法返回时,发出调用的线程必须等待重新输入同步域。

适用于

SignalAndWait(WaitHandle, WaitHandle, TimeSpan, Boolean)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

发出信号并等待另一个 WaitHandle ,将超时间隔指定为 TimeSpan 超时间隔,并指定是否在输入等待之前退出上下文的同步域。

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

参数

toSignal
WaitHandle

WaitHandle 发出信号。

toWaitOn
WaitHandle

等待 WaitHandle

timeout
TimeSpan

表示要等待的间隔的 A TimeSpan 。 如果值为 -1,则等待是无限的。

exitContext
Boolean

true 如果处于同步上下文中,请在等待之前退出上下文的同步域(如果在同步的上下文中),然后重新获取它;否则,为 false.

返回

true 如果信号和等待都成功完成,或者 false 信号已完成,但等待超时。

例外

toSignalnull

-或-

toWaitOnnull

该方法在处于状态的 STA 线程上调用。

toSignal 是信号灯,并且已具有完整计数。

timeout 计算结果为除 -1 以外的负数毫秒。

-或-

timeout 大于 Int32.MaxValue

等待已完成,因为线程退出而不释放互斥体。

注解

此操作不保证为原子操作。 在当前线程发出信号 toSignal 但等待 toWaitOn之前,在另一个处理器上运行的线程可能会发出信号 toWaitOn 或等待。

的最大值 timeoutInt32.MaxValue.

如果 timeout 为零,则该方法不会阻止。 它会测试状态 toWaitOn 并立即返回。

退出上下文

除非从非默认托管上下文内部调用此方法,否则参数 exitContext 不起作用。 如果线程在对派生自 ContextBoundObject的类实例的调用中,则托管上下文可以是非默认上下文。 即使当前在未派生自 ContextBoundObject的类上执行方法,例如 String,如果在 ContextBoundObject 当前应用程序域中的堆栈上,也可以位于非默认上下文中。

当代码在非默认上下文中执行时,指定 trueexitContext 会导致线程在执行此方法之前退出非默认托管上下文(即转换到默认上下文)。 调用此方法后,线程将返回到原始非默认上下文。

当上下文绑定类具有 SynchronizationAttribute 属性时,退出上下文可能很有用。 在这种情况下,对类成员的所有调用都会自动同步,并且同步域是该类的整个代码正文。 如果成员调用堆栈中的代码调用此方法并指定 trueexitContext则线程将退出同步域,从而允许在调用对象的任何成员时阻止的线程继续。 此方法返回时,发出调用的线程必须等待重新输入同步域。

适用于