WaitHandle.WaitAny 方法

定義

等待指定陣列中的任一元件接收訊號。

多載

名稱 Description
WaitAny(WaitHandle[])

等待指定陣列中的任一元件接收訊號。

WaitAny(WaitHandle[], Int32)

等待指定陣列中任一元素接收訊號,並使用 32 位元有符號整數指定時間區間。

WaitAny(WaitHandle[], TimeSpan)

等待指定陣列中的任一元素接收訊號,並使用 a TimeSpan 來指定時間區間。

WaitAny(WaitHandle[], Int32, Boolean)

等待指定陣列中的任一元素接收訊號,使用32位元有符號整數指定時間區間,並指定是否在等待前退出同步域。

WaitAny(WaitHandle[], TimeSpan, Boolean)

等待指定陣列中的任一元素接收訊號,利用 a TimeSpan 指定時間區間,並決定是否在等待前退出同步域。

WaitAny(WaitHandle[])

來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs

等待指定陣列中的任一元件接收訊號。

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles);
public static int WaitAny(System.Threading.WaitHandle[] waitHandles);
static member WaitAny : System.Threading.WaitHandle[] -> int
Public Shared Function WaitAny (waitHandles As WaitHandle()) As Integer

參數

waitHandles
WaitHandle[]

一個 WaitHandle 陣列,包含目前實例將等待的物件。

傳回

滿足等待條件的物件的陣列索引。

例外狀況

參數 waitHandlesnull

-或-

陣列中的 waitHandles 一個或多個物件為 null

物件 waitHandles 數量超過系統允許的範圍。

waitHandles 是一個沒有元素的陣列,.NET Framework 版本為 1.0 或 1.1。

等待結束是因為執行緒退出時未釋放 mutex。

waitHandles 是一個無元素的陣列,.NET Framework 版本為 2.0 或更新版本。

waitHandles 列包含另一個應用域中 a WaitHandle 的透明代理。

範例

以下程式碼範例示範呼叫該 WaitAny 方法。

using System;
using System.Threading;

public sealed class App
{
    // Define an array with two AutoResetEvent WaitHandles.
    static WaitHandle[] waitHandles = new WaitHandle[]
    {
        new AutoResetEvent(false),
        new AutoResetEvent(false)
    };

    // Define a random number generator for testing.
    static Random r = new Random();

    static void Main()
    {
        // Queue up two tasks on two different threads;
        // wait until all tasks are completed.
        DateTime dt = DateTime.Now;
        Console.WriteLine("Main thread is waiting for BOTH tasks to complete.");
        ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
        ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
        WaitHandle.WaitAll(waitHandles);
        // The time shown below should match the longest task.
        Console.WriteLine("Both tasks are completed (time waited={0})",
            (DateTime.Now - dt).TotalMilliseconds);

        // Queue up two tasks on two different threads;
        // wait until any task is completed.
        dt = DateTime.Now;
        Console.WriteLine();
        Console.WriteLine("The main thread is waiting for either task to complete.");
        ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
        ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
        int index = WaitHandle.WaitAny(waitHandles);
        // The time shown below should match the shortest task.
        Console.WriteLine("Task {0} finished first (time waited={1}).",
            index + 1, (DateTime.Now - dt).TotalMilliseconds);
    }

    static void DoTask(Object state)
    {
        AutoResetEvent are = (AutoResetEvent) state;
        int time = 1000 * r.Next(2, 10);
        Console.WriteLine("Performing a task for {0} milliseconds.", time);
        Thread.Sleep(time);
        are.Set();
    }
}

// This code produces output similar to the following:
//
//  Main thread is waiting for BOTH tasks to complete.
//  Performing a task for 7000 milliseconds.
//  Performing a task for 4000 milliseconds.
//  Both tasks are completed (time waited=7064.8052)
//
//  The main thread is waiting for either task to complete.
//  Performing a task for 2000 milliseconds.
//  Performing a task for 2000 milliseconds.
//  Task 1 finished first (time waited=2000.6528).
Imports System.Threading

NotInheritable Public Class App
    ' Define an array with two AutoResetEvent WaitHandles.
    Private Shared waitHandles() As WaitHandle = _
        {New AutoResetEvent(False), New AutoResetEvent(False)}
    
    ' Define a random number generator for testing.
    Private Shared r As New Random()
    
    <MTAThreadAttribute> _
    Public Shared Sub Main() 
        ' Queue two tasks on two different threads; 
        ' wait until all tasks are completed.
        Dim dt As DateTime = DateTime.Now
        Console.WriteLine("Main thread is waiting for BOTH tasks to complete.")
        ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(0))
        ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(1))
        WaitHandle.WaitAll(waitHandles)
        ' The time shown below should match the longest task.
        Console.WriteLine("Both tasks are completed (time waited={0})", _
            (DateTime.Now - dt).TotalMilliseconds)
        
        ' Queue up two tasks on two different threads; 
        ' wait until any tasks are completed.
        dt = DateTime.Now
        Console.WriteLine()
        Console.WriteLine("The main thread is waiting for either task to complete.")
        ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(0))
        ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(1))
        Dim index As Integer = WaitHandle.WaitAny(waitHandles)
        ' The time shown below should match the shortest task.
        Console.WriteLine("Task {0} finished first (time waited={1}).", _
            index + 1,(DateTime.Now - dt).TotalMilliseconds)
    
    End Sub
    
    Shared Sub DoTask(ByVal state As [Object]) 
        Dim are As AutoResetEvent = CType(state, AutoResetEvent)
        Dim time As Integer = 1000 * r.Next(2, 10)
        Console.WriteLine("Performing a task for {0} milliseconds.", time)
        Thread.Sleep(time)
        are.Set()
    
    End Sub
End Class

' This code produces output similar to the following:
'
'  Main thread is waiting for BOTH tasks to complete.
'  Performing a task for 7000 milliseconds.
'  Performing a task for 4000 milliseconds.
'  Both tasks are completed (time waited=7064.8052)
' 
'  The main thread is waiting for either task to complete.
'  Performing a task for 2000 milliseconds.
'  Performing a task for 2000 milliseconds.
'  Task 1 finished first (time waited=2000.6528).

備註

AbandonedMutexException 是 .NET Framework 2.0 版本中新增的。 在先前版本中, WaitAny 若等待完成且因靜止子被放棄,該方法會回傳 true 。 遺棄的互斥體通常表示存在嚴重的編碼錯誤。 在系統範圍的互斥系統中,可能表示應用程式已被突然終止(例如使用Windows工作管理員)。 例外包含對除錯有用的資訊。

WaitAny當等待結束時,該方法會拋出 only AbandonedMutexException ,因為有遺棄的 mutex。 若 waitHandles 包含一個釋放的互斥體,其索引號低於放棄的互斥體, WaitAny 則方法正常完成且不拋出例外。

Note

在 2.0 版本之前的 .NET Framework 版本中,若執行緒退出或中止時未明確釋出 Mutex,且該 Mutex 在另一執行緒的 WaitAny 陣列中位於索引 0(0),WaitAny 回傳的索引將是 128,而非 0。

當任何句柄被訊號時,此方法會回傳。 若呼叫過程中有多個物件被訊號,回傳值即為該訊號物件的陣列索引,索引最小於所有訊號物件中。

等待處理次數最多為 64 個,若執行緒處於 STA 狀態狀態則為 63 個。

呼叫此方法過載等同於呼叫 WaitAny(WaitHandle[], Int32, Boolean) 方法過載,並為 且 指定 -1(或 Timeout.Infinite)為 millisecondsTimeouttrueexitContext

適用於

WaitAny(WaitHandle[], Int32)

來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs

等待指定陣列中任一元素接收訊號,並使用 32 位元有符號整數指定時間區間。

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout);
public static int WaitAny(System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout);
static member WaitAny : System.Threading.WaitHandle[] * int -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), millisecondsTimeout As Integer) As Integer

參數

waitHandles
WaitHandle[]

一個 WaitHandle 陣列,包含目前實例將等待的物件。

millisecondsTimeout
Int32

等待的時間,或無限等待的毫秒數,或 Infinite 是(-1)無限等待的時間。

傳回

滿足等待的物件的陣列索引,或WaitTimeout若無物件滿足等待,且時間區間等同於 。millisecondsTimeout

例外狀況

參數 waitHandlesnull

-或-

陣列中的 waitHandles 一個或多個物件為 null

物件 waitHandles 數量超過系統允許的範圍。

millisecondsTimeout 是除 -1 以外的負數,而 -1 代表無限次超時。

等待結束是因為執行緒退出時未釋放 mutex。

waitHandles 是一個沒有元素的陣列。

waitHandles 列包含另一個應用域中 a WaitHandle 的透明代理。

備註

millisecondsTimeout 為零,則該方法不會阻塞。 它會測試等待處理的狀態,並立即返回。

WaitAny當等待結束時,該方法會拋出 only AbandonedMutexException ,因為有遺棄的 mutex。 若 waitHandles 包含一個釋放的互斥體,其索引號低於放棄的互斥體, WaitAny 則方法正常完成且不拋出例外。

此方法在等待結束時回傳,無論是任一句柄被發出訊號,或是逾時發生。 若呼叫過程中有多個物件被訊號,回傳值即為該訊號物件的陣列索引,索引最小於所有訊號物件中。

等待處理次數最多為 64 個,若執行緒處於 STA 狀態狀態則為 63 個。

呼叫此方法的超載,等同於呼叫過 WaitAny(WaitHandle[], Int32, Boolean) 載並指定 falseexitContext

適用於

WaitAny(WaitHandle[], TimeSpan)

來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs

等待指定陣列中的任一元素接收訊號,並使用 a TimeSpan 來指定時間區間。

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout);
public static int WaitAny(System.Threading.WaitHandle[] waitHandles, TimeSpan timeout);
static member WaitAny : System.Threading.WaitHandle[] * TimeSpan -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), timeout As TimeSpan) As Integer

參數

waitHandles
WaitHandle[]

一個 WaitHandle 陣列,包含目前實例將等待的物件。

timeout
TimeSpan

TimeSpan A 代表等待的毫秒數,或 A TimeSpan 代表無限等待的 -1 毫秒。

傳回

滿足等待的物件的陣列索引,或WaitTimeout若無物件滿足等待,且時間區間等同於 。timeout

例外狀況

參數 waitHandlesnull

-或-

陣列中的 waitHandles 一個或多個物件為 null

物件 waitHandles 數量超過系統允許的範圍。

timeout 是除 -1 毫秒外的負數,代表無限次逾時。

-或-

timeout 大於 Int32.MaxValue

等待結束是因為執行緒退出時未釋放 mutex。

waitHandles 是一個沒有元素的陣列。

waitHandles 列包含另一個應用域中 a WaitHandle 的透明代理。

備註

timeout 為零,則該方法不會阻塞。 它會測試等待處理的狀態,並立即返回。

WaitAny當等待結束時,該方法會拋出 only AbandonedMutexException ,因為有遺棄的 mutex。 若 waitHandles 包含一個釋放的互斥體,其索引號低於放棄的互斥體, WaitAny 則方法正常完成且不拋出例外。

此方法在等待結束時回傳,無論是任一代柄被發出訊號或逾時。 若呼叫過程中有多個物件被訊號,回傳值即為該訊號物件的陣列索引,索引最小於所有訊號物件中。

等待處理次數最多為 64 個,若執行緒處於 STA 狀態狀態則為 63 個。

最大 timeout 值為 Int32.MaxValue

呼叫此方法的超載,等同於呼叫過 WaitAny(WaitHandle[], TimeSpan, Boolean) 載並指定 falseexitContext

適用於

WaitAny(WaitHandle[], Int32, Boolean)

來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs

等待指定陣列中的任一元素接收訊號,使用32位元有符號整數指定時間區間,並指定是否在等待前退出同步域。

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout, bool exitContext);
public static int WaitAny(System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext);
static member WaitAny : System.Threading.WaitHandle[] * int * bool -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), millisecondsTimeout As Integer, exitContext As Boolean) As Integer

參數

waitHandles
WaitHandle[]

一個 WaitHandle 陣列,包含目前實例將等待的物件。

millisecondsTimeout
Int32

等待的時間,或無限等待的毫秒數,或 Infinite 是(-1)無限等待的時間。

exitContext
Boolean

true在等待前退出上下文的同步域(若在同步上下文中),並在等待後重新取得;否則,。 false

傳回

滿足等待的物件的陣列索引,或WaitTimeout若無物件滿足等待,且時間區間等同於 。millisecondsTimeout

例外狀況

參數 waitHandlesnull

-或-

陣列中的 waitHandles 一個或多個物件為 null

物件 waitHandles 數量超過系統允許的範圍。

waitHandles 是一個沒有元素的陣列,.NET Framework 版本為 1.0 或 1.1。

millisecondsTimeout 是除 -1 以外的負數,而 -1 代表無限次超時。

等待結束是因為執行緒退出時未釋放 mutex。

waitHandles 是一個無元素的陣列,.NET Framework 版本為 2.0 或更新版本。

waitHandles 列包含另一個應用域中 a WaitHandle 的透明代理。

範例

以下程式碼範例示範如何利用執行緒池同時在多個磁碟上搜尋檔案。 為了空間考量,僅搜尋每個磁碟的根目錄。

using System;
using System.IO;
using System.Threading;

class Test
{
    static void Main()
    {
        Search search = new Search();
        search.FindFile("SomeFile.dat");
    }
}

class Search
{
    // Maintain state information to pass to FindCallback.
    class State
    {
        public AutoResetEvent autoEvent;
        public string         fileName;

        public State(AutoResetEvent autoEvent, string fileName)
        {
            this.autoEvent    = autoEvent;
            this.fileName     = fileName;
        }
    }

    AutoResetEvent[] autoEvents;
    String[] diskLetters;

    public Search()
    {
        // Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives();

        autoEvents = new AutoResetEvent[diskLetters.Length];
        for(int i = 0; i < diskLetters.Length; i++)
        {
            autoEvents[i] = new AutoResetEvent(false);
        }
    }

    // Search for fileName in the root directory of all disks.
    public void FindFile(string fileName)
    {
        for(int i = 0; i < diskLetters.Length; i++)
        {
            Console.WriteLine("Searching for {0} on {1}.",
                fileName, diskLetters[i]);
            ThreadPool.QueueUserWorkItem(
                new WaitCallback(FindCallback), 
                new State(autoEvents[i], diskLetters[i] + fileName));
        }

        // Wait for the first instance of the file to be found.
        int index = WaitHandle.WaitAny(autoEvents, 3000, false);
        if(index == WaitHandle.WaitTimeout)
        {
            Console.WriteLine("\n{0} not found.", fileName);
        }
        else
        {
            Console.WriteLine("\n{0} found on {1}.", fileName,
                diskLetters[index]);
        }
    }

    // Search for stateInfo.fileName.
    void FindCallback(object state)
    {
        State stateInfo = (State)state;

        // Signal if the file is found.
        if(File.Exists(stateInfo.fileName))
        {
            stateInfo.autoEvent.Set();
        }
    }
}
Imports System.IO
Imports System.Threading

Public Class Test

    <MTAThread> _
    Shared Sub Main()
        Dim search As New Search()
        search.FindFile("SomeFile.dat")
    End Sub    
End Class

Public Class Search

    ' Maintain state information to pass to FindCallback.
    Class State
        Public autoEvent As AutoResetEvent 
        Public fileName As String         

        Sub New(anEvent As AutoResetEvent, fName As String)
            autoEvent = anEvent
            fileName = fName
        End Sub
    End Class

    Dim autoEvents() As AutoResetEvent
    Dim diskLetters() As String

    Sub New()

        ' Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives()

        autoEvents = New AutoResetEvent(diskLetters.Length - 1) {}
        For i As Integer = 0 To diskLetters.Length - 1
            autoEvents(i) = New AutoResetEvent(False)
        Next i
    End Sub    
    
    ' Search for fileName in the root directory of all disks.
    Sub FindFile(fileName As String)
        For i As Integer = 0 To diskLetters.Length - 1
            Console.WriteLine("Searching for {0} on {1}.", _
                fileName, diskLetters(i))
        
            ThreadPool.QueueUserWorkItem(AddressOf FindCallback, _ 
                New State(autoEvents(i), diskLetters(i) & fileName))
        Next i

        ' Wait for the first instance of the file to be found.
        Dim index As Integer = _
            WaitHandle.WaitAny(autoEvents, 3000, False)
        If index = WaitHandle.WaitTimeout
            Console.WriteLine(vbCrLf & "{0} not found.", fileName)
        Else
            Console.WriteLine(vbCrLf & "{0} found on {1}.", _
                fileName, diskLetters(index))
        End If
    End Sub

    ' Search for stateInfo.fileName.
    Sub FindCallback(state As Object)
        Dim stateInfo As State = DirectCast(state, State)

        ' Signal if the file is found.
        If File.Exists(stateInfo.fileName) Then
            stateInfo.autoEvent.Set()
        End If
    End Sub

End Class

備註

millisecondsTimeout 為零,則該方法不會阻塞。 它會測試等待處理的狀態,並立即返回。

WaitAny當等待結束時,該方法會拋出 only AbandonedMutexException ,因為有遺棄的 mutex。 若 waitHandles 包含一個釋放的互斥體,其索引號低於放棄的互斥體, WaitAny 則方法正常完成且不拋出例外。 遺棄的互斥體通常表示存在嚴重的編碼錯誤。 在系統範圍的互斥系統中,可能表示應用程式已被突然終止(例如使用Windows工作管理員)。 例外包含對除錯有用的資訊。

此方法在等待結束時回傳,無論是任一句柄被發出訊號,或是逾時發生。 若呼叫過程中有多個物件被訊號,回傳值即為該訊號物件的陣列索引,索引最小於所有訊號物件中。

等待處理次數最多為 64 個,若執行緒處於 STA 狀態狀態則為 63 個。

退出語境

除非此方法在非預設的受管理上下文中呼叫,否則該 exitContext 參數不會產生影響。 如果你的執行緒位於從 衍生 ContextBoundObject的類別實例呼叫中,該受管理上下文可以是非預設的。 即使你目前執行的是一個不是源自 ContextBoundObject的類別,例如 String,只要 a ContextBoundObject 在當前應用域的堆疊中,你也可以處於非預設的上下文中。

當你的程式碼在非預設上下文中執行時,指定 true for exitContext 會讓執行緒在執行此方法前退出非預設的管理上下文(也就是轉換到預設上下文)。 執行緒在呼叫完成後會回到原始非預設上下文。

當上下文綁定類別擁有 屬性 SynchronizationAttribute 時,退出上下文會很有用。 在此情況下,對類別成員的所有呼叫都會自動同步處理,而且同步處理網域是 類別的整個程式代碼主體。 如果成員呼叫堆疊中的程式碼呼叫此方法並指定 trueexitContext,該執行緒將退出同步域,允許被阻擋呼叫物件中任一成員的執行緒繼續。 當此方法回傳時,呼叫的執行緒必須等待重新進入同步域。

適用於

WaitAny(WaitHandle[], TimeSpan, Boolean)

來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
WaitHandle.cs

等待指定陣列中的任一元素接收訊號,利用 a TimeSpan 指定時間區間,並決定是否在等待前退出同步域。

public:
 static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout, bool exitContext);
public static int WaitAny(System.Threading.WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext);
static member WaitAny : System.Threading.WaitHandle[] * TimeSpan * bool -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), timeout As TimeSpan, exitContext As Boolean) As Integer

參數

waitHandles
WaitHandle[]

一個 WaitHandle 陣列,包含目前實例將等待的物件。

timeout
TimeSpan

TimeSpan A 代表等待的毫秒數,或 A TimeSpan 代表無限等待的 -1 毫秒。

exitContext
Boolean

true在等待前退出上下文的同步域(若在同步上下文中),並在等待後重新取得;否則,。 false

傳回

滿足等待的物件的陣列索引,或WaitTimeout若無物件滿足等待,且時間區間等同於 。timeout

例外狀況

參數 waitHandlesnull

-或-

陣列中的 waitHandles 一個或多個物件為 null

物件 waitHandles 數量超過系統允許的範圍。

waitHandles 是一個沒有元素的陣列,.NET Framework 版本為 1.0 或 1.1。

timeout 是除 -1 毫秒外的負數,代表無限次逾時。

-或-

timeout 大於 Int32.MaxValue

等待結束是因為執行緒退出時未釋放 mutex。

waitHandles 是一個無元素的陣列,.NET Framework 版本為 2.0 或更新版本。

waitHandles 列包含另一個應用域中 a WaitHandle 的透明代理。

範例

以下程式碼範例示範如何利用執行緒池同時在多個磁碟上搜尋檔案。 為了空間考量,僅搜尋每個磁碟的根目錄。

using System;
using System.IO;
using System.Threading;

class Test
{
    static void Main()
    {
        Search search = new Search();
        search.FindFile("SomeFile.dat");
    }
}

class Search
{
    // Maintain state information to pass to FindCallback.
    class State
    {
        public AutoResetEvent autoEvent;
        public string         fileName;

        public State(AutoResetEvent autoEvent, string fileName)
        {
            this.autoEvent    = autoEvent;
            this.fileName     = fileName;
        }
    }

    AutoResetEvent[] autoEvents;
    String[] diskLetters;

    public Search()
    {
        // Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives();

        autoEvents = new AutoResetEvent[diskLetters.Length];
        for(int i = 0; i < diskLetters.Length; i++)
        {
            autoEvents[i] = new AutoResetEvent(false);
        }
    }

    // Search for fileName in the root directory of all disks.
    public void FindFile(string fileName)
    {
        for(int i = 0; i < diskLetters.Length; i++)
        {
            Console.WriteLine("Searching for {0} on {1}.",
                fileName, diskLetters[i]);
            ThreadPool.QueueUserWorkItem(
                new WaitCallback(FindCallback), 
                new State(autoEvents[i], diskLetters[i] + fileName));
        }

        // Wait for the first instance of the file to be found.
        int index = WaitHandle.WaitAny(
            autoEvents, new TimeSpan(0, 0, 3), false);
        if(index == WaitHandle.WaitTimeout)
        {
            Console.WriteLine("\n{0} not found.", fileName);
        }
        else
        {
            Console.WriteLine("\n{0} found on {1}.", fileName,
                diskLetters[index]);
        }
    }

    // Search for stateInfo.fileName.
    void FindCallback(object state)
    {
        State stateInfo = (State)state;

        // Signal if the file is found.
        if(File.Exists(stateInfo.fileName))
        {
            stateInfo.autoEvent.Set();
        }
    }
}
Imports System.IO
Imports System.Threading

Public Class Test

    <MTAThread> _
    Shared Sub Main()
        Dim search As New Search()
        search.FindFile("SomeFile.dat")
    End Sub    
End Class

Public Class Search

    ' Maintain state information to pass to FindCallback.
    Class State
        Public autoEvent As AutoResetEvent 
        Public fileName As String         

        Sub New(anEvent As AutoResetEvent, fName As String)
            autoEvent = anEvent
            fileName = fName
        End Sub
    End Class

    Dim autoEvents() As AutoResetEvent
    Dim diskLetters() As String

    Sub New()

        ' Retrieve an array of disk letters.
        diskLetters = Environment.GetLogicalDrives()

        autoEvents = New AutoResetEvent(diskLetters.Length - 1) {}
        For i As Integer = 0 To diskLetters.Length - 1
            autoEvents(i) = New AutoResetEvent(False)
        Next i
    End Sub    
    
    ' Search for fileName in the root directory of all disks.
    Sub FindFile(fileName As String)
        For i As Integer = 0 To diskLetters.Length - 1
            Console.WriteLine("Searching for {0} on {1}.", _
                fileName, diskLetters(i))
        
            ThreadPool.QueueUserWorkItem(AddressOf FindCallback, _ 
                New State(autoEvents(i), diskLetters(i) & fileName))
        Next i

        ' Wait for the first instance of the file to be found.
        Dim index As Integer = WaitHandle.WaitAny( _
            autoEvents, New TimeSpan(0, 0, 3), False)
        If index = WaitHandle.WaitTimeout
            Console.WriteLine(vbCrLf & "{0} not found.", fileName)
        Else
            Console.WriteLine(vbCrLf & "{0} found on {1}.", _
                fileName, diskLetters(index))
        End If
    End Sub

    ' Search for stateInfo.fileName.
    Sub FindCallback(state As Object)
        Dim stateInfo As State = DirectCast(state, State)

        ' Signal if the file is found.
        If File.Exists(stateInfo.fileName) Then
            stateInfo.autoEvent.Set()
        End If
    End Sub

End Class

備註

timeout 為零,則該方法不會阻塞。 它會測試等待處理的狀態,並立即返回。

WaitAny當等待結束時,該方法會拋出 only AbandonedMutexException ,因為有遺棄的 mutex。 若 waitHandles 包含一個釋放的互斥體,其索引號低於放棄的互斥體, WaitAny 則方法正常完成且不拋出例外。 遺棄的互斥體通常表示存在嚴重的編碼錯誤。 在系統範圍的互斥系統中,可能表示應用程式已被突然終止(例如使用Windows工作管理員)。 例外包含對除錯有用的資訊。

此方法在等待結束時回傳,無論是任一代柄被發出訊號或逾時。 若呼叫過程中有多個物件被訊號,回傳值即為該訊號物件的陣列索引,索引最小於所有訊號物件中。

等待處理次數最多為 64 個,若執行緒處於 STA 狀態狀態則為 63 個。

最大 timeout 值為 Int32.MaxValue

退出語境

除非此方法在非預設的受管理上下文中呼叫,否則該 exitContext 參數不會產生影響。 如果你的執行緒位於從 衍生 ContextBoundObject的類別實例呼叫中,該受管理上下文可以是非預設的。 即使你目前執行的是一個不是源自 ContextBoundObject的類別,例如 String,只要 a ContextBoundObject 在當前應用域的堆疊中,你也可以處於非預設的上下文中。

當你的程式碼在非預設上下文中執行時,指定 true for exitContext 會讓執行緒在執行此方法前退出非預設的管理上下文(也就是轉換到預設上下文)。 執行緒在呼叫完成後會回到原始非預設上下文。

當上下文綁定類別擁有 屬性 SynchronizationAttribute 時,退出上下文會很有用。 在此情況下,對類別成員的所有呼叫都會自動同步處理,而且同步處理網域是 類別的整個程式代碼主體。 如果成員呼叫堆疊中的程式碼呼叫此方法並指定 trueexitContext,該執行緒將退出同步域,允許被阻擋呼叫物件中任一成員的執行緒繼續。 當此方法回傳時,呼叫的執行緒必須等待重新進入同步域。

適用於