WaitHandle.WaitOne 方法

定义

阻止当前线程,直到当前 WaitHandle 接收信号。

重载

名称 说明
WaitOne()

阻止当前线程,直到当前 WaitHandle 接收信号。

WaitOne(Int32)

阻止当前线程,直到当前 WaitHandle 接收信号,使用 32 位有符号整数指定时间间隔(以毫秒为单位)。

WaitOne(TimeSpan)

阻止当前线程,直到当前实例收到信号,并使用 TimeSpan 指定时间间隔。

WaitOne(Int32, Boolean)

阻止当前线程,直到当前 WaitHandle 接收信号,使用 32 位有符号整数指定时间间隔,并指定是否在等待之前退出同步域。

WaitOne(TimeSpan, Boolean)

阻止当前线程,直到当前实例收到信号,使用指定 TimeSpan 时间间隔并指定是否在等待之前退出同步域。

WaitOne()

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

阻止当前线程,直到当前 WaitHandle 接收信号。

public:
 virtual bool WaitOne();
public virtual bool WaitOne();
abstract member WaitOne : unit -> bool
override this.WaitOne : unit -> bool
Public Overridable Function WaitOne () As Boolean

返回

true 如果当前实例收到信号,则为 。 如果当前实例从未发出信号, WaitOne() 则永远不会返回。

例外

当前实例已释放。

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

当前实例是另一个应用程序域中的 WaitHandle 透明代理。

示例

下面的代码示例演示如何使用等待句柄来防止进程在等待后台线程完成执行时终止。

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

注解

AbandonedMutexException 是 .NET Framework 版本 2.0 中的新增功能。 在以前的版本中,此方法 WaitOnetrue 放弃互斥体时返回。 放弃的互斥体通常表示存在严重的编码错误。 对于系统范围的互斥体,它可能表示应用程序已突然终止(例如,使用 Windows 任务管理器)。 异常包含可用于调试的信息。

此方法的调用方无限期地阻止,直到当前实例收到信号。 使用此方法阻止, WaitHandle 直到收到来自另一个线程的信号,例如在异步操作完成时生成。 有关详细信息,请参阅 IAsyncResult 该接口。

调用此方法重载等效于调用 WaitOne(Int32, Boolean) 方法重载并指定 -1 或 Timeout.Infinite 第一个参数和第 false 二个参数。

重写此方法以自定义派生类的行为。

适用于

WaitOne(Int32)

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

阻止当前线程,直到当前 WaitHandle 接收信号,使用 32 位有符号整数指定时间间隔(以毫秒为单位)。

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

参数

millisecondsTimeout
Int32

等待的毫秒数,或 Infinite (-1)无限期等待。

返回

true 如果当前实例收到信号,则为 ;否则,为 false.

例外

当前实例已释放。

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

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

当前实例是另一个应用程序域中的 WaitHandle 透明代理。

示例

下面的代码示例演示如何使用等待句柄来防止进程在等待后台线程完成执行时终止。

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

注解

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

此方法的调用方会阻止,直到当前实例收到信号或超时。 使用此方法阻止, WaitHandle 直到收到来自另一个线程的信号,例如在异步操作完成时生成。 有关详细信息,请参阅 IAsyncResult 该接口。

重写此方法以自定义派生类的行为。

调用此方法重载与调用WaitOne(Int32, Boolean)重载和指定falseexitContext重载相同。

适用于

WaitOne(TimeSpan)

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

阻止当前线程,直到当前实例收到信号,并使用 TimeSpan 指定时间间隔。

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

参数

timeout
TimeSpan

一个 TimeSpan 表示等待的毫秒数,或 TimeSpan 表示要无限期等待的 -1 毫秒。

返回

true 如果当前实例收到信号,则为 ;否则,为 false.

例外

当前实例已释放。

timeout 是一个负数,而不是 -1 毫秒,表示无限超时。

-或-

timeout 大于 Int32.MaxValue

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

当前实例是另一个应用程序域中的 WaitHandle 透明代理。

注解

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

此方法的调用方会阻止,直到当前实例收到信号或超时。 使用此方法阻止, WaitHandle 直到收到来自另一个线程的信号,例如在异步操作完成时生成。 有关详细信息,请参阅 IAsyncResult 该接口。

重写此方法以自定义派生类的行为。

的最大值 timeoutInt32.MaxValue.

调用此方法重载与调用WaitOne(TimeSpan, Boolean)重载和指定falseexitContext重载相同。

适用于

WaitOne(Int32, Boolean)

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

阻止当前线程,直到当前 WaitHandle 接收信号,使用 32 位有符号整数指定时间间隔,并指定是否在等待之前退出同步域。

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

参数

millisecondsTimeout
Int32

等待的毫秒数,或 Infinite (-1)无限期等待。

exitContext
Boolean

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

返回

true 如果当前实例收到信号,则为 ;否则,为 false.

例外

当前实例已释放。

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

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

当前实例是另一个应用程序域中的 WaitHandle 透明代理。

示例

以下示例演示方法 WaitOne(Int32, Boolean) 重载在同步域中调用时的行为方式。 首先,线程将等待设置为exitContextfalse和阻止,直到等待超时过期。 第二个线程在第一个线程终止后执行,等待设置为 < a0/> 。 不会阻止对第二个线程的等待句柄发出信号的调用,并且线程在等待超时之前完成。

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

注解

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

如果放弃互斥体,则会引发一个 AbandonedMutexException 。 放弃的互斥体通常表示存在严重的编码错误。 对于系统范围的互斥体,它可能表示应用程序已突然终止(例如,使用 Windows 任务管理器)。 异常包含可用于调试的信息。

此方法的调用方会阻止,直到当前实例收到信号或超时。 使用此方法阻止, WaitHandle 直到收到来自另一个线程的信号,例如在异步操作完成时生成。 有关详细信息,请参阅 IAsyncResult 该接口。

重写此方法以自定义派生类的行为。

退出上下文

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

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

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

适用于

WaitOne(TimeSpan, Boolean)

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

阻止当前线程,直到当前实例收到信号,使用指定 TimeSpan 时间间隔并指定是否在等待之前退出同步域。

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

参数

timeout
TimeSpan

一个 TimeSpan 表示等待的毫秒数,或 TimeSpan 表示要无限期等待的 -1 毫秒。

exitContext
Boolean

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

返回

true 如果当前实例收到信号,则为 ;否则,为 false.

例外

当前实例已释放。

timeout 是一个负数,而不是 -1 毫秒,表示无限超时。

-或-

timeout 大于 Int32.MaxValue

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

当前实例是另一个应用程序域中的 WaitHandle 透明代理。

示例

下面的代码示例演示如何使用等待句柄来防止进程在等待后台线程完成执行时终止。

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

注解

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

如果放弃互斥体,则会引发一个 AbandonedMutexException 。 放弃的互斥体通常表示存在严重的编码错误。 对于系统范围的互斥体,它可能表示应用程序已突然终止(例如,使用 Windows 任务管理器)。 异常包含可用于调试的信息。

此方法的调用方会阻止,直到当前实例收到信号或超时。 使用此方法阻止, WaitHandle 直到收到来自另一个线程的信号,例如在异步操作完成时生成。 有关详细信息,请参阅 IAsyncResult 该接口。

重写此方法以自定义派生类的行为。

的最大值 timeoutInt32.MaxValue.

退出上下文

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

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

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

适用于