WaitHandle.WaitOne 方法
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
阻止当前线程,直到当前 WaitHandle 收到信号。
重载
WaitOne() |
阻止当前线程,直到当前 WaitHandle 收到信号。 |
WaitOne(Int32) |
阻止当前线程,直到当前 WaitHandle 收到信号,同时使用 32 位带符号整数指定时间间隔(以毫秒为单位)。 |
WaitOne(TimeSpan) |
阻止当前线程,直到当前实例收到信号,同时使用 TimeSpan 指定时间间隔。 |
WaitOne(Int32, Boolean) |
阻止当前线程,直到当前的 WaitHandle 收到信号为止,同时使用 32 位带符号整数指定时间间隔,并指定是否在等待之前退出同步域。 |
WaitOne(TimeSpan, Boolean) |
阻止当前线程,直到当前实例收到信号为止,同时使用 TimeSpan 指定时间间隔,并指定是否在等待之前退出同步域。 |
WaitOne()
阻止当前线程,直到当前 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 namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
WaitOne(){}
public:
static void WorkMethod( Object^ stateInfo )
{
Console::WriteLine( "Work starting." );
// Simulate time spent working.
Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
// Signal that work is finished.
Console::WriteLine( "Work ending." );
dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
}
};
int main()
{
Console::WriteLine( "Main starting." );
AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::WorkMethod ), autoEvent );
// Wait for work method to signal.
autoEvent->WaitOne( );
Console::WriteLine( "Work method signaled.\nMain ending." );
}
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
放弃互斥体时,该方法将返回。 被放弃的 mutex 通常表明出现了严重的编码错误。 对于系统范围内的互斥体,它可能指示应用程序突然终止 (例如,通过使用 Windows 任务管理器) 。 此异常包含用于调试的信息。
此方法的调用方会无限期阻止,直到当前实例收到信号。 使用此方法可在 WaitHandle 接收来自另一个线程的信号之前进行阻止,如在异步操作完成时生成。 有关详细信息,请参阅 IAsyncResult 接口。
调用此方法重载等效于调用 WaitOne(Int32, Boolean) 方法重载,并将 Timeout.Infinite 第一个参数和第 false
二个参数指定为-1 或。
重写此方法以自定义派生类的行为。
适用于
WaitOne(Int32)
阻止当前线程,直到当前 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 的负数,而 -1 表示无限期超时。
等待结束,因为线程在未释放互斥的情况下退出。
当前实例是另一个应用程序域中的 WaitHandle 的透明代理。
示例
下面的代码示例演示如何使用等待句柄来防止进程在等待后台线程完成执行时终止。
using namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
WaitOne(){}
public:
static void WorkMethod( Object^ stateInfo )
{
Console::WriteLine( "Work starting." );
// Simulate time spent working.
Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
// Signal that work is finished.
Console::WriteLine( "Work ending." );
dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
}
};
int main()
{
Console::WriteLine( "Main starting." );
AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::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." );
}
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) 重载并为指定 false
的相同 exitContext
。
适用于
WaitOne(TimeSpan)
阻止当前线程,直到当前实例收到信号,同时使用 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) 重载并为指定 false
的相同 exitContext
。
适用于
WaitOne(Int32, Boolean)
阻止当前线程,直到当前的 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 的负数,而 -1 表示无限期超时。
等待结束,因为线程在未释放互斥的情况下退出。
当前实例是另一个应用程序域中的 WaitHandle 的透明代理。
示例
下面的示例演示 WaitOne(Int32, Boolean) 方法重载在同步域中调用时的行为方式。 首先,线程 exitContext
将设置为 false
并在等待超时过期之前进行阻止。 第一个线程在第一个线程终止并等待 exitContext
设置为时执行 true
。 对此第二个线程的等待句柄发出信号的调用未被阻止,线程在等待超时前完成。
using namespace System;
using namespace System::Threading;
using namespace System::Runtime::Remoting::Contexts;
[Synchronization(true)]
public ref class SyncingClass : ContextBoundObject
{
private:
EventWaitHandle^ waitHandle;
public:
SyncingClass()
{
waitHandle =
gcnew EventWaitHandle(false, EventResetMode::ManualReset);
}
void Signal()
{
Console::WriteLine("Thread[{0:d4}]: Signalling...", Thread::CurrentThread->GetHashCode());
waitHandle->Set();
}
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 ref class TestSyncDomainWait
{
public:
static void Main()
{
SyncingClass^ syncClass = gcnew SyncingClass();
Thread^ runWaiter;
Console::WriteLine("\nWait and signal INSIDE synchronization domain:\n");
runWaiter = gcnew Thread(gcnew ParameterizedThreadStart(&TestSyncDomainWait::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 = gcnew Thread(gcnew ParameterizedThreadStart(&TestSyncDomainWait::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();
}
static void RunWaitKeepContext(Object^ parm)
{
((SyncingClass^)parm)->DoWait(false);
}
static void RunWaitLeaveContext(Object^ parm)
{
((SyncingClass^)parm)->DoWait(true);
}
};
int main()
{
TestSyncDomainWait::Main();
}
// 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!!!
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是 .NET Framework 版本2.0 中的新增项。 在以前的版本中,在 WaitOne true
放弃互斥体时,该方法将返回。 被放弃的 mutex 通常表明出现了严重的编码错误。 对于系统范围内的互斥体,它可能指示应用程序突然终止 (例如,通过使用 Windows 任务管理器) 。 此异常包含用于调试的信息。
此方法的调用方会一直阻止,直到当前实例收到信号或发生超时。 使用此方法可在 WaitHandle 接收来自另一个线程的信号之前进行阻止,如在异步操作完成时生成。 有关详细信息,请参阅 IAsyncResult 接口。
重写此方法以自定义派生类的行为。
有关退出上下文的说明
exitContext
除非 WaitOne 从非默认托管上下文内调用方法,否则参数不起作用。 如果你的线程在对从派生的类的实例的调用中,则可能会发生这种情况 ContextBoundObject 。 即使当前正在对不是从派生的类(如)执行方法, ContextBoundObject 如果在 String ContextBoundObject 当前应用程序域中的堆栈上,也可以在非默认上下文中执行。
当你的代码在非默认上下文中执行时,为指定将 true
exitContext
导致线程退出非默认的托管上下文 (也就是说,在执行方法前转换为默认上下文) WaitOne 。 调用方法完成后,线程返回到原始的非默认上下文 WaitOne 。
当上下文绑定类具有时,这会很有用 SynchronizationAttribute 。 在这种情况下,对类成员的所有调用都将自动同步,同步域是类的整个代码正文。 如果成员的调用堆栈中的代码调用 WaitOne 方法并 true
为指定 exitContext
,则线程将退出同步域,从而允许在对对象的任何成员的调用上被阻止的线程继续。 当 WaitOne 方法返回时,进行调用的线程必须等待重新进入同步域。
适用于
WaitOne(TimeSpan, Boolean)
阻止当前线程,直到当前实例收到信号为止,同时使用 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 namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
WaitOne(){}
public:
static void WorkMethod( Object^ stateInfo )
{
Console::WriteLine( "Work starting." );
// Simulate time spent working.
Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
// Signal that work is finished.
Console::WriteLine( "Work ending." );
dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
}
};
int main()
{
Console::WriteLine( "Main starting." );
AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::WorkMethod ), autoEvent );
// Wait for work method to signal.
if ( autoEvent->WaitOne( 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." );
}
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是 .NET Framework 版本2.0 中的新增项。 在以前的版本中,在 WaitOne true
放弃互斥体时,该方法将返回。 被放弃的 mutex 通常表明出现了严重的编码错误。 对于系统范围内的互斥体,它可能指示应用程序突然终止 (例如,通过使用 Windows 任务管理器) 。 此异常包含用于调试的信息。
此方法的调用方会一直阻止,直到当前实例收到信号或发生超时。 使用此方法可在 WaitHandle 接收来自另一个线程的信号之前进行阻止,如在异步操作完成时生成。 有关详细信息,请参阅 IAsyncResult 接口。
重写此方法以自定义派生类的行为。
的最大值 timeout
为 Int32.MaxValue 。
有关退出上下文的说明
exitContext
除非 WaitOne 从非默认托管上下文内调用方法,否则参数不起作用。 如果你的线程在对从派生的类的实例的调用中,则可能会发生这种情况 ContextBoundObject 。 即使当前正在对不是从派生的类(如)执行方法, ContextBoundObject 如果在 String ContextBoundObject 当前应用程序域中的堆栈上,也可以在非默认上下文中执行。
当你的代码在非默认上下文中执行时,为指定将 true
exitContext
导致线程退出非默认的托管上下文 (也就是说,在执行方法前转换为默认上下文) WaitOne 。 调用方法完成后,线程返回到原始的非默认上下文 WaitOne 。
当上下文绑定类具有时,这会很有用 SynchronizationAttribute 。 在这种情况下,对类成员的所有调用都将自动同步,同步域是类的整个代码正文。 如果成员的调用堆栈中的代码调用 WaitOne 方法并 true
为指定 exitContext
,则线程将退出同步域,从而允许在对对象的任何成员的调用上被阻止的线程继续。 当 WaitOne 方法返回时,进行调用的线程必须等待重新进入同步域。