WaitHandle.WaitOne WaitHandle.WaitOne WaitHandle.WaitOne WaitHandle.WaitOne Method

定义

阻止当前线程,直到当前 WaitHandle 收到信号。Blocks the current thread until the current WaitHandle receives a signal.

重载

WaitOne() WaitOne() WaitOne() WaitOne()

阻止当前线程,直到当前 WaitHandle 收到信号。Blocks the current thread until the current WaitHandle receives a signal.

WaitOne(Int32) WaitOne(Int32) WaitOne(Int32) WaitOne(Int32)

阻止当前线程,直到当前 WaitHandle 收到信号,同时使用 32 位带符号整数指定时间间隔(以毫秒为单位)。Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval in milliseconds.

WaitOne(TimeSpan) WaitOne(TimeSpan) WaitOne(TimeSpan) WaitOne(TimeSpan)

阻止当前线程,直到当前实例收到信号,同时使用 TimeSpan 指定时间间隔。Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval.

WaitOne(Int32, Boolean) WaitOne(Int32, Boolean) WaitOne(Int32, Boolean) WaitOne(Int32, Boolean)

阻止当前线程,直到当前的 WaitHandle 收到信号为止,同时使用 32 位带符号整数指定时间间隔,并指定是否在等待之前退出同步域。Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval and specifying whether to exit the synchronization domain before the wait.

WaitOne(TimeSpan, Boolean) WaitOne(TimeSpan, Boolean) WaitOne(TimeSpan, Boolean) WaitOne(TimeSpan, Boolean)

阻止当前线程,直到当前实例收到信号为止,同时使用 TimeSpan 指定时间间隔,并指定是否在等待之前退出同步域。Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval and specifying whether to exit the synchronization domain before the wait.

WaitOne() WaitOne() WaitOne() WaitOne()

阻止当前线程,直到当前 WaitHandle 收到信号。Blocks the current thread until the current WaitHandle receives a signal.

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

返回

如果当前实例收到信号,则为 truetrue if the current instance receives a signal. 如果当前实例永不发出信号,则 WaitOne(Int32, Boolean) 永不返回。If the current instance is never signaled, WaitOne(Int32, Boolean) never returns.

异常

已释放当前实例。The current instance has already been disposed.

等待结束,因为线程在未释放互斥的情况下退出。The wait completed because a thread exited without releasing a mutex. 在 Windows 98 或 Windows Millennium Edition 上不会引发此异常。This exception is not thrown on Windows 98 or Windows Millennium Edition.

当前实例是另一个应用程序域中的 WaitHandle 的透明代理。The current instance is a transparent proxy for a WaitHandle in another application domain.

示例

下面的代码示例演示如何使用等待句柄以防止进程终止等待后台线程完成执行时。The following code example shows how to use a wait handle to keep a process from terminating while it waits for a background thread to finish executing.

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
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 版中的新增功能。AbandonedMutexException is new in the .NET Framework version 2.0. 在上一版本中,WaitOne方法将返回true时放弃的互斥体。In previous versions, the WaitOne method returns true when a mutex is abandoned. 放弃的 mutex 通常表明存在严重的编码错误。An abandoned mutex often indicates a serious coding error. 在系统范围的情况下它可能指示,已突然终止应用程序 (例如,通过使用 Windows 任务管理器)。In the case of a system-wide mutex, it might indicate that an application has been terminated abruptly (for example, by using Windows Task Manager). 该异常包含有关调试的有用信息。The exception contains information useful for debugging.

此方法进行阻止,直到当前实例无限期的调用方收到信号。The caller of this method blocks indefinitely until the current instance receives a signal. 使用此方法进行阻止,直至WaitHandle从另一个线程收到信号,例如则会生成异步操作完成时。Use this method to block until a WaitHandle receives a signal from another thread, such as is generated when an asynchronous operation completes. 有关详细信息,请参阅IAsyncResult接口。For more information, see the IAsyncResult interface.

调用此方法重载是等效于调用WaitOne(Int32, Boolean)方法重载并指定-1 或Timeout.Infinite第一个参数和false为第二个参数。Calling this method overload is equivalent to calling the WaitOne(Int32, Boolean) method overload and specifying -1 or Timeout.Infinite for the first parameter and false for the second parameter.

重写此方法以自定义派生类的行为。Override this method to customize the behavior of derived classes.

WaitOne(Int32) WaitOne(Int32) WaitOne(Int32) WaitOne(Int32)

阻止当前线程,直到当前 WaitHandle 收到信号,同时使用 32 位带符号整数指定时间间隔(以毫秒为单位)。Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval in milliseconds.

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

等待的毫秒数,或为 Infinite (-1),表示无限期等待。The number of milliseconds to wait, or Infinite (-1) to wait indefinitely.

返回

如果当前实例收到信号,则为 true;否则为 falsetrue if the current instance receives a signal; otherwise, false.

异常

已释放当前实例。The current instance has already been disposed.

millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。millisecondsTimeout is a negative number other than -1, which represents an infinite time-out.

等待结束,因为线程在未释放互斥的情况下退出。The wait completed because a thread exited without releasing a mutex. 在 Windows 98 或 Windows Millennium Edition 上不会引发此异常。This exception is not thrown on Windows 98 or Windows Millennium Edition.

当前实例是另一个应用程序域中的 WaitHandle 的透明代理。The current instance is a transparent proxy for a WaitHandle in another application domain.

示例

下面的代码示例演示如何使用等待句柄以防止进程终止等待后台线程完成执行时。The following code example shows how to use a wait handle to keep a process from terminating while it waits for a background thread to finish executing.

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
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为零,该方法不会阻止。If millisecondsTimeout is zero, the method does not block. 它测试等待句柄的状态并立即返回。It tests the state of the wait handle and returns immediately.

此方法受到阻止,直到当前实例收到信号或超时的调用方会发生。The caller of this method blocks until the current instance receives a signal or a time-out occurs. 使用此方法进行阻止,直至WaitHandle从另一个线程收到信号,例如则会生成异步操作完成时。Use this method to block until a WaitHandle receives a signal from another thread, such as is generated when an asynchronous operation completes. 有关详细信息,请参阅IAsyncResult接口。For more information, see the IAsyncResult interface.

重写此方法以自定义派生类的行为。Override this method to customize the behavior of derived classes.

调用此方法的重载相当于调用WaitOne(Int32, Boolean)重载并指定falseexitContextCalling this method overload is the same as calling the WaitOne(Int32, Boolean) overload and specifying false for exitContext.

WaitOne(TimeSpan) WaitOne(TimeSpan) WaitOne(TimeSpan) WaitOne(TimeSpan)

阻止当前线程,直到当前实例收到信号,同时使用 TimeSpan 指定时间间隔。Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval.

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 TimeSpan

表示等待毫秒数的 TimeSpan,或表示 -1 毫秒(无限期等待)的 TimeSpanA TimeSpan that represents the number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely.

返回

如果当前实例收到信号,则为 true;否则为 falsetrue if the current instance receives a signal; otherwise, false.

异常

已释放当前实例。The current instance has already been disposed.

timeout 为 -1 毫秒以外的负数,表示无限期超时。timeout is a negative number other than -1 milliseconds, which represents an infinite time-out. - 或 --or- timeout 大于 MaxValuetimeout is greater than MaxValue.

等待结束,因为线程在未释放互斥的情况下退出。The wait completed because a thread exited without releasing a mutex. 在 Windows 98 或 Windows Millennium Edition 上不会引发此异常。This exception is not thrown on Windows 98 or Windows Millennium Edition.

当前实例是另一个应用程序域中的 WaitHandle 的透明代理。The current instance is a transparent proxy for a WaitHandle in another application domain.

注解

如果timeout为零,该方法不会阻止。If timeout is zero, the method does not block. 它测试等待句柄的状态并立即返回。It tests the state of the wait handle and returns immediately.

此方法受到阻止,直到当前实例收到信号或超时的调用方会发生。The caller of this method blocks until the current instance receives a signal or a time-out occurs. 使用此方法进行阻止,直至WaitHandle从另一个线程收到信号,例如则会生成异步操作完成时。Use this method to block until a WaitHandle receives a signal from another thread, such as is generated when an asynchronous operation completes. 有关详细信息,请参阅IAsyncResult接口。For more information, see the IAsyncResult interface.

重写此方法以自定义派生类的行为。Override this method to customize the behavior of derived classes.

最大值timeoutInt32.MaxValueThe maximum value for timeout is Int32.MaxValue.

调用此方法的重载相当于调用WaitOne(TimeSpan, Boolean)重载并指定falseexitContextCalling this method overload is the same as calling the WaitOne(TimeSpan, Boolean) overload and specifying false for exitContext.

WaitOne(Int32, Boolean) WaitOne(Int32, Boolean) WaitOne(Int32, Boolean) WaitOne(Int32, Boolean)

阻止当前线程,直到当前的 WaitHandle 收到信号为止,同时使用 32 位带符号整数指定时间间隔,并指定是否在等待之前退出同步域。Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval and specifying whether to exit the synchronization domain before the wait.

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

等待的毫秒数,或为 Infinite (-1),表示无限期等待。The number of milliseconds to wait, or Infinite (-1) to wait indefinitely.

exitContext
Boolean Boolean Boolean Boolean

如果等待之前先退出上下文的同步域(如果在同步上下文中),并在稍后重新获取它,则为 true;否则为 falsetrue to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it afterward; otherwise, false.

返回

如果当前实例收到信号,则为 true;否则为 falsetrue if the current instance receives a signal; otherwise, false.

异常

已释放当前实例。The current instance has already been disposed.

millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。millisecondsTimeout is a negative number other than -1, which represents an infinite time-out.

等待结束,因为线程在未释放互斥的情况下退出。The wait completed because a thread exited without releasing a mutex. 在 Windows 98 或 Windows Millennium Edition 上不会引发此异常。This exception is not thrown on Windows 98 or Windows Millennium Edition.

当前实例是另一个应用程序域中的 WaitHandle 的透明代理。The current instance is a transparent proxy for a WaitHandle in another application domain.

示例

下面的示例演示如何将WaitOne(Int32, Boolean)方法重载的行为与在一个域中同步调用时。The following example shows how the WaitOne(Int32, Boolean) method overload behaves when it is called within a synchronization domain. 首先的线程在等待exitContext设置为false并阻止,直到等待超时过期。First, a thread waits with exitContext set to false and blocks until the wait timeout expires. 第二个线程执行后的第一个线程终止,并使用在等待exitContext设置为trueA second thread executes after the first thread terminates and waits with exitContext set to true. 此第二个线程的等待句柄发送信号的调用未被阻止,并在线程等待超时前完成。The call to signal the wait handle for this second thread is not blocked, and the thread completes before the wait timeout.

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
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(vbNewLine + "Wait and signal INSIDE synchronization domain:" + vbNewLine)
        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(vbNewLine + "Wait and signal OUTSIDE synchronization domain:" + vbNewLine)
        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为零,该方法不会阻止。If millisecondsTimeout is zero, the method does not block. 它测试等待句柄的状态并立即返回。It tests the state of the wait handle and returns immediately.

AbandonedMutexException 是.NET Framework 2.0 版中的新增功能。AbandonedMutexException is new in the .NET Framework version 2.0. 在上一版本中,WaitOne方法将返回true时放弃的互斥体。In previous versions, the WaitOne method returns true when a mutex is abandoned. 放弃的 mutex 通常表明存在严重的编码错误。An abandoned mutex often indicates a serious coding error. 在系统范围的情况下它可能指示,已突然终止应用程序 (例如,通过使用 Windows 任务管理器)。In the case of a system-wide mutex, it might indicate that an application has been terminated abruptly (for example, by using Windows Task Manager). 该异常包含有关调试的有用信息。The exception contains information useful for debugging.

此方法受到阻止,直到当前实例收到信号或超时的调用方会发生。The caller of this method blocks until the current instance receives a signal or a time-out occurs. 使用此方法进行阻止,直至WaitHandle从另一个线程收到信号,例如则会生成异步操作完成时。Use this method to block until a WaitHandle receives a signal from another thread, such as is generated when an asynchronous operation completes. 有关详细信息,请参阅IAsyncResult接口。For more information, see the IAsyncResult interface.

重写此方法以自定义派生类的行为。Override this method to customize the behavior of derived classes.

在退出上下文的说明Notes on Exiting the Context

exitContext参数无任何效果,除非WaitOne从非默认托管上下文中调用方法。The exitContext parameter has no effect unless the WaitOne method is called from inside a nondefault managed context. 如果你的线程是派生自的类的实例的调用内部发生这种情况ContextBoundObjectThis can happen if your thread is inside a call to an instance of a class derived from ContextBoundObject. 即使当前正在执行一种方法不是派生的类上ContextBoundObject,例如String,可以在非默认上下文中是如果ContextBoundObject是当前的应用程序域中的堆栈上。Even if you are currently executing a method on a class that does not derive from ContextBoundObject, like String, you can be in a nondefault context if a ContextBoundObject is on your stack in the current application domain.

时在非默认上下文中执行代码时,指定true有关exitContext会导致线程退出非默认托管的上下文 (即,转换到默认上下文) 执行前WaitOne方法。When your code is executing in a nondefault context, specifying true for exitContext causes the thread to exit the nondefault managed context (that is, to transition to the default context) before executing the WaitOne method. 线程在调用后返回到原始的非默认上下文WaitOne方法完成。The thread returns to the original nondefault context after the call to the WaitOne method completes.

在上下文绑定类时这很有用SynchronizationAttributeThis can be useful when the context-bound class has SynchronizationAttribute. 在这种情况下,所有调用的类的成员将自动都同步,并同步域是为类代码的整个正文。In that case, all calls to members of the class are automatically synchronized, and the synchronization domain is the entire body of code for the class. 如果某个成员的调用堆栈中的代码将调用WaitOne方法,并指定trueexitContext,在线程退出同步域,这样在调用对象的任何成员以继续操作被阻止的线程。If code in the call stack of a member calls the WaitOne method and specifies true for exitContext, the thread exits the synchronization domain, allowing a thread that is blocked on a call to any member of the object to proceed. WaitOne方法返回时,调用线程必须等待以重新输入同步域。When the WaitOne method returns, the thread that made the call must wait to reenter the synchronization domain.

WaitOne(TimeSpan, Boolean) WaitOne(TimeSpan, Boolean) WaitOne(TimeSpan, Boolean) WaitOne(TimeSpan, Boolean)

阻止当前线程,直到当前实例收到信号为止,同时使用 TimeSpan 指定时间间隔,并指定是否在等待之前退出同步域。Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval and specifying whether to exit the synchronization domain before the wait.

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 TimeSpan

表示等待毫秒数的 TimeSpan,或表示 -1 毫秒(无限期等待)的 TimeSpanA TimeSpan that represents the number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely.

exitContext
Boolean Boolean Boolean Boolean

如果等待之前先退出上下文的同步域(如果在同步上下文中),并在稍后重新获取它,则为 true;否则为 falsetrue to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it afterward; otherwise, false.

返回

如果当前实例收到信号,则为 true;否则为 falsetrue if the current instance receives a signal; otherwise, false.

异常

已释放当前实例。The current instance has already been disposed.

timeout 为 -1 毫秒以外的负数,表示无限期超时。timeout is a negative number other than -1 milliseconds, which represents an infinite time-out. - 或 --or- timeout 大于 MaxValuetimeout is greater than MaxValue.

等待结束,因为线程在未释放互斥的情况下退出。The wait completed because a thread exited without releasing a mutex. 在 Windows 98 或 Windows Millennium Edition 上不会引发此异常。This exception is not thrown on Windows 98 or Windows Millennium Edition.

当前实例是另一个应用程序域中的 WaitHandle 的透明代理。The current instance is a transparent proxy for a WaitHandle in another application domain.

示例

下面的代码示例演示如何使用等待句柄以防止进程终止等待后台线程完成执行时。The following code example shows how to use a wait handle to keep a process from terminating while it waits for a background thread to finish executing.

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
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为零,该方法不会阻止。If timeout is zero, the method does not block. 它测试等待句柄的状态并立即返回。It tests the state of the wait handle and returns immediately.

AbandonedMutexException 是.NET Framework 2.0 版中的新增功能。AbandonedMutexException is new in the .NET Framework version 2.0. 在上一版本中,WaitOne方法将返回true时放弃的互斥体。In previous versions, the WaitOne method returns true when a mutex is abandoned. 放弃的 mutex 通常表明存在严重的编码错误。An abandoned mutex often indicates a serious coding error. 在系统范围的情况下它可能指示,已突然终止应用程序 (例如,通过使用 Windows 任务管理器)。In the case of a system-wide mutex, it might indicate that an application has been terminated abruptly (for example, by using Windows Task Manager). 该异常包含有关调试的有用信息。The exception contains information useful for debugging.

此方法受到阻止,直到当前实例收到信号或超时的调用方会发生。The caller of this method blocks until the current instance receives a signal or a time-out occurs. 使用此方法进行阻止,直至WaitHandle从另一个线程收到信号,例如则会生成异步操作完成时。Use this method to block until a WaitHandle receives a signal from another thread, such as is generated when an asynchronous operation completes. 有关详细信息,请参阅IAsyncResult接口。For more information, see the IAsyncResult interface.

重写此方法以自定义派生类的行为。Override this method to customize the behavior of derived classes.

最大值timeoutInt32.MaxValueThe maximum value for timeout is Int32.MaxValue.

在退出上下文的说明Notes on Exiting the Context

exitContext参数无任何效果,除非WaitOne从非默认托管上下文中调用方法。The exitContext parameter has no effect unless the WaitOne method is called from inside a nondefault managed context. 如果你的线程是派生自的类的实例的调用内部发生这种情况ContextBoundObjectThis can happen if your thread is inside a call to an instance of a class derived from ContextBoundObject. 即使当前正在执行一种方法不是派生的类上ContextBoundObject,例如String,可以在非默认上下文中是如果ContextBoundObject是当前的应用程序域中的堆栈上。Even if you are currently executing a method on a class that does not derive from ContextBoundObject, like String, you can be in a nondefault context if a ContextBoundObject is on your stack in the current application domain.

时在非默认上下文中执行代码时,指定true有关exitContext会导致线程退出非默认托管的上下文 (即,转换到默认上下文) 执行前WaitOne方法。When your code is executing in a nondefault context, specifying true for exitContext causes the thread to exit the nondefault managed context (that is, to transition to the default context) before executing the WaitOne method. 线程在调用后返回到原始的非默认上下文WaitOne方法完成。The thread returns to the original nondefault context after the call to the WaitOne method completes.

在上下文绑定类时这很有用SynchronizationAttributeThis can be useful when the context-bound class has SynchronizationAttribute. 在这种情况下,所有调用的类的成员将自动都同步,并同步域是为类代码的整个正文。In that case, all calls to members of the class are automatically synchronized, and the synchronization domain is the entire body of code for the class. 如果某个成员的调用堆栈中的代码将调用WaitOne方法,并指定trueexitContext,在线程退出同步域,这样在调用对象的任何成员以继续操作被阻止的线程。If code in the call stack of a member calls the WaitOne method and specifies true for exitContext, the thread exits the synchronization domain, allowing a thread that is blocked on a call to any member of the object to proceed. WaitOne方法返回时,调用线程必须等待以重新输入同步域。When the WaitOne method returns, the thread that made the call must wait to reenter the synchronization domain.

适用于