WaitHandle.WaitOne 方法

定義

封鎖目前的執行緒,直到目前的 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() 就一定不會傳回。

例外狀況

目前的執行個體已經過處置。

由於執行緒結束時未釋放 Mutex,已完成等候。

目前的執行個體是另一個應用程式定義域中 WaitHandle 的 Transparent Proxy。

範例

下列程式代碼範例示範如何使用等候句柄,讓進程在等候背景線程完成執行時,使其無法終止。

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 時傳回。 放棄的 Mutex 通常表示嚴重的編碼錯誤。 在全系統 Mutex 的情況下,它可能表示應用程式已突然終止 (,例如使用 Windows 任務管理員) 。 例外狀況包含可用於偵錯的資訊。

此方法的呼叫端會無限期地封鎖,直到目前的實例收到訊號為止。 使用此方法封鎖,直到 WaitHandle 收到來自另一個線程的訊號,例如異步操作完成時產生。 如需詳細資訊,請參閱 IAsyncResult 介面。

呼叫這個方法多載相當於呼叫 WaitOne(Int32, Boolean) 方法多載,並指定 -1 或 Timeout.Infinite 第一個參數,以及 false 第二個參數。

覆寫這個方法以自定義衍生類別的行為。

適用於

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

參數

millisecondsTimeout
Int32

要等候的毫秒數,如果要無限期等候,則為 Infinite (-1)。

傳回

如果目前的執行個體收到信號,則為 true,否則為 false

例外狀況

目前的執行個體已經過處置。

millisecondsTimeout 為 -1 以外的負數,表示無限逾時。

由於執行緒結束時未釋放 Mutex,已完成等候。

目前的執行個體是另一個應用程式定義域中 WaitHandle 的 Transparent Proxy。

範例

下列程式代碼範例示範如何使用等候句柄,讓進程在等候背景線程完成執行時,使其無法終止。

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) 多載相同,並針對 exitContext指定 false

適用於

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

參數

timeout
TimeSpan

TimeSpan,代表等候毫秒數;或是 TimeSpan,代表無限期等候的 -1 毫秒。

傳回

如果目前的執行個體收到信號,則為 true,否則為 false

例外狀況

目前的執行個體已經過處置。

timeout 為 -1 毫秒以外的負數,表示無限逾時。

-或-

timeout 大於 Int32.MaxValue

由於執行緒結束時未釋放 Mutex,已完成等候。

目前的執行個體是另一個應用程式定義域中 WaitHandle 的 Transparent Proxy。

備註

如果 timeout 為零,則方法不會封鎖。 它會測試等候句柄的狀態,並立即傳回 。

此方法的呼叫端會封鎖,直到目前的實例收到訊號或逾時為止。 使用此方法封鎖,直到 WaitHandle 收到來自另一個線程的訊號,例如異步操作完成時產生。 如需詳細資訊,請參閱 IAsyncResult 介面。

覆寫這個方法以自定義衍生類別的行為。

的最大值 timeoutInt32.MaxValue

呼叫這個方法多載與呼叫 WaitOne(TimeSpan, Boolean) 多載相同,並針對 exitContext指定 false

適用於

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

參數

millisecondsTimeout
Int32

要等候的毫秒數,如果要無限期等候,則為 Infinite (-1)。

exitContext
Boolean

true 表示在等候 (如果在同步內容中) 前結束內容的同步處理網域,並於之後重新取得,否則為 false

傳回

如果目前的執行個體收到信號,則為 true,否則為 false

例外狀況

目前的執行個體已經過處置。

millisecondsTimeout 為 -1 以外的負數,表示無限逾時。

由於執行緒結束時未釋放 Mutex,已完成等候。

目前的執行個體是另一個應用程式定義域中 WaitHandle 的 Transparent Proxy。

範例

下列範例顯示方法多載在同步處理網域內呼叫時的行為 WaitOne(Int32, Boolean) 。 首先,線程會等候設定 exitContextfalse 並封鎖,直到等候逾時到期為止。 第二個線程會在第一個線程終止之後執行,並等候設定 exitContexttrue。 發出此第二個線程等候句柄的訊號呼叫不會遭到封鎖,而且線程會在等候逾時之前完成。

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 為零,則方法不會封鎖。 它會測試等候句柄的狀態,並立即傳回 。

如果放棄 Mutex, AbandonedMutexException 則會擲回 。 放棄的 Mutex 通常表示嚴重的編碼錯誤。 在全系統 Mutex 的情況下,它可能表示應用程式已突然終止 (,例如使用 Windows 任務管理員) 。 例外狀況包含可用於偵錯的資訊。

此方法的呼叫端會封鎖,直到目前的實例收到訊號或逾時為止。 使用此方法封鎖,直到 WaitHandle 收到來自另一個線程的訊號,例如異步操作完成時產生。 如需詳細資訊,請參閱 IAsyncResult 介面。

覆寫這個方法以自定義衍生類別的行為。

結束內容

exitContext除非從非預設 Managed 內容內呼叫這個方法,否則參數沒有作用。 如果您的線程位於衍生自 ContextBoundObject之類別實例的呼叫內,則Managed內容可以是非預設的。 即使您目前正在不是衍生自 ContextBoundObject的類別上執行方法,例如 String,如果在 ContextBoundObject 目前應用程式域中的堆疊上,您仍可以位於非預設內容中。

當您的程式代碼在非預設內容中執行時,指定 true 會導致 exitContext 線程結束非預設受控內容 (,也就是在執行此方法之前轉換至默認內容) 。 線程會在呼叫這個方法完成之後,傳回原始的非預設內容。

當內容系結類別具有 SynchronizationAttribute 屬性時,結束內容可能會很有用。 在此情況下,類別成員的所有呼叫都會自動同步處理,而且同步處理網域是類別的整個程式代碼主體。 如果成員呼叫堆疊中的程式代碼呼叫此方法並指定 trueexitContext,則線程會結束同步處理網域,這可讓呼叫物件的任何成員上封鎖的線程繼續進行。 當這個方法傳回時,發出呼叫的線程必須等候重新進入同步處理網域。

適用於

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

參數

timeout
TimeSpan

TimeSpan,代表等候毫秒數;或是 TimeSpan,代表無限期等候的 -1 毫秒。

exitContext
Boolean

true 表示在等候 (如果在同步內容中) 前結束內容的同步處理網域,並於之後重新取得,否則為 false

傳回

如果目前的執行個體收到信號,則為 true,否則為 false

例外狀況

目前的執行個體已經過處置。

timeout 為 -1 毫秒以外的負數,表示無限逾時。

-或-

timeout 大於 Int32.MaxValue

由於執行緒結束時未釋放 Mutex,已完成等候。

目前的執行個體是另一個應用程式定義域中 WaitHandle 的 Transparent Proxy。

範例

下列程式代碼範例示範如何使用等候句柄,讓進程在等候背景線程完成執行時,使其無法終止。

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 為零,則方法不會封鎖。 它會測試等候句柄的狀態,並立即傳回。

如果放棄 mutex, AbandonedMutexException 則會擲回 。 已放棄的 Mutex 通常表示嚴重的程式代碼撰寫錯誤。 在全系統 Mutex 的情況下,它可能表示應用程式已突然終止 (例如,使用 Windows 任務管理員) 。 例外狀況包含適用於偵錯的資訊。

這個方法的呼叫端會封鎖,直到目前的實例收到訊號或發生逾時為止。 使用此方法封鎖,直到 WaitHandle 收到來自另一個線程的訊號為止,例如在異步操作完成時產生。 如需詳細資訊,請參閱 IAsyncResult 介面。

覆寫這個方法以自定義衍生類別的行為。

最大 timeout 值為 Int32.MaxValue

結束內容

exitContext除非從非預設 Managed 內容內呼叫這個方法,否則參數不會有任何作用。 如果您的線程位於衍生自 ContextBoundObject之類別實例的呼叫內,則Managed內容可以是非預設的。 即使您目前正在不是衍生自 ContextBoundObject的類別上執行方法,例如 String,如果 ContextBoundObject 位於目前應用程式域中的堆疊上,您也可以在非預設內容中。

當您的程式代碼在非預設內容中執行時,指定 trueexitContext 會導致線程結束非預設受控內容 (,也就是在執行此方法之前轉換至默認內容) 。 呼叫這個方法之後,線程會傳回原始的非預設內容。

當內容系結類別具有 SynchronizationAttribute 屬性時,結束內容可能會很有用。 在此情況下,類別成員的所有呼叫都會自動同步處理,而同步處理網域則是類別的整個程式代碼主體。 如果成員呼叫堆疊中的程式代碼呼叫這個方法並指定 trueexitContext,線程會結束同步處理網域,這允許在呼叫物件的任何成員時封鎖的線程繼續進行。 當這個方法傳回時,進行呼叫的線程必須等候重新進入同步處理網域。

適用於