WaitHandle.WaitOne 方法
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
阻止当前线程,直到当前 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 中的新增功能。 在以前的版本中,此方法 WaitOne 在 true 放弃互斥体时返回。 放弃的互斥体通常表示存在严重的编码错误。 对于系统范围的互斥体,它可能表示应用程序已突然终止(例如,使用 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
参数
返回
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
参数
返回
true 如果当前实例收到信号,则为 ;否则,为 false.
例外
当前实例已释放。
等待已完成,因为线程退出而不释放互斥体。
当前实例是另一个应用程序域中的 WaitHandle 透明代理。
注解
如果 timeout 为零,则该方法不会阻止。 它会测试等待句柄的状态并立即返回。
此方法的调用方会阻止,直到当前实例收到信号或超时。 使用此方法阻止, WaitHandle 直到收到来自另一个线程的信号,例如在异步操作完成时生成。 有关详细信息,请参阅 IAsyncResult 该接口。
重写此方法以自定义派生类的行为。
的最大值 timeout 为 Int32.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
参数
- 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 当前应用程序域中的堆栈上,也可以位于非默认上下文中。
当代码在非默认上下文中执行时,指定 true 它 exitContext 会导致线程在执行此方法之前退出非默认托管上下文(即转换到默认上下文)。 调用此方法后,线程将返回到原始非默认上下文。
当上下文绑定类具有 SynchronizationAttribute 属性时,退出上下文可能很有用。 在这种情况下,对类成员的所有调用都会自动同步,并且同步域是该类的整个代码正文。 如果成员调用堆栈中的代码调用此方法并指定 true , exitContext则线程将退出同步域,从而允许在调用对象的任何成员时阻止的线程继续。 此方法返回时,发出调用的线程必须等待重新输入同步域。
适用于
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
参数
- exitContext
- Boolean
true 如果处于同步上下文中,请在等待之前退出上下文的同步域(如果在同步的上下文中),然后重新获取它;否则,为 false.
返回
true 如果当前实例收到信号,则为 ;否则,为 false.
例外
当前实例已释放。
等待已完成,因为线程退出而不释放互斥体。
当前实例是另一个应用程序域中的 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 该接口。
重写此方法以自定义派生类的行为。
的最大值 timeout 为 Int32.MaxValue.
退出上下文
除非从非默认托管上下文内部调用此方法,否则参数 exitContext 不起作用。 如果线程在对派生自 ContextBoundObject的类实例的调用中,则托管上下文可以是非默认上下文。 即使当前在未派生自 ContextBoundObject的类上执行方法,例如 String,如果在 ContextBoundObject 当前应用程序域中的堆栈上,也可以位于非默认上下文中。
当代码在非默认上下文中执行时,指定 true 它 exitContext 会导致线程在执行此方法之前退出非默认托管上下文(即转换到默认上下文)。 调用此方法后,线程将返回到原始非默认上下文。
当上下文绑定类具有 SynchronizationAttribute 属性时,退出上下文可能很有用。 在这种情况下,对类成员的所有调用都会自动同步,并且同步域是该类的整个代码正文。 如果成员调用堆栈中的代码调用此方法并指定 true , exitContext则线程将退出同步域,从而允许在调用对象的任何成员时阻止的线程继续。 此方法返回时,发出调用的线程必须等待重新输入同步域。