WaitHandle.WaitAny 方法

定义

等待指定数组中的任一元素收到信号。

重载

WaitAny(WaitHandle[])

等待指定数组中的任一元素收到信号。

WaitAny(WaitHandle[], Int32)

等待指定数组中的任意元素接收信号,同时使用 32 位有符号整数指定时间间隔。

WaitAny(WaitHandle[], TimeSpan)

等待指定数组中的任意元素接收信号,同时使用 TimeSpan 指定时间间隔。

WaitAny(WaitHandle[], Int32, Boolean)

等待指定数组中的任一元素收到信号,使用 32 位带符号整数指定时间间隔并指定是否在等待之前退出同步域。

WaitAny(WaitHandle[], TimeSpan, Boolean)

等待指定数组中的任一元素收到信号,使用 TimeSpan 指定时间间隔并指定是否在等待之前退出同步域。

WaitAny(WaitHandle[])

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

等待指定数组中的任一元素收到信号。

public static int WaitAny (System.Threading.WaitHandle[] waitHandles);

参数

waitHandles
WaitHandle[]

一个 WaitHandle 数组,包含当前实例将等待的对象。

返回

满足等待的对象的数组索引。

例外

waitHandles 参数为 null

- 或 -

waitHandles 数组中一个或多个对象为 null

waitHandles 中的对象数大于系统允许的数量。

waitHandles 是不含元素的数组,并且 .NET Framework 的版本为 1.0 或 1.1。

等待结束,因为线程在未释放互斥的情况下退出。

waitHandles 是不含元素的数组,并且 .NET Framework 的版本为 2.0 或更高。

waitHandles 数组包含其他应用程序域中 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).

注解

AbandonedMutexException是 .NET Framework 2.0 版中的新增功能。 在以前的版本中, WaitAny 如果由于互斥被放弃而等待完成,则方法将返回 true 。 放弃的互斥体通常表示存在严重的编码错误。 对于系统范围的互斥,它可能表示应用程序已突然终止 (,例如,使用 Windows 任务管理器) 。 异常包含对调试有用的信息。

仅当等待由于放弃的互斥体而完成时,方法 WaitAny 才会引发 AbandonedMutexException 。 如果 waitHandles 包含的已释放互斥体具有比放弃的互斥体低的索引号,则 WaitAny 该方法将正常完成,并且不会引发异常。

备注

在低于版本 2.0 的.NET Framework版本中,如果线程退出或中止而不显式释放 ,并且Mutex另一个MutexWaitAny线程的数组中的索引为 0 (零) ,则 返回WaitAny的索引为 128 而不是 0。

此方法在发出任何句柄信号时返回。 如果在调用期间发出多个对象的信号,则返回值是信号对象的数组索引,其索引值是所有信号对象的最小索引值。

等待句柄的最大数目为 64;如果当前线程处于 STA 状态,则为 63。

调用此方法重载等效于调用 WaitAny(WaitHandle[], Int32, Boolean) 方法重载并为 指定 -1 (或 Timeout.Infinite) truemillisecondsTimeoutexitContext

适用于

.NET 9 和其他版本
产品 版本
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

WaitAny(WaitHandle[], Int32)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

等待指定数组中的任意元素接收信号,同时使用 32 位有符号整数指定时间间隔。

public static int WaitAny (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout);

参数

waitHandles
WaitHandle[]

一个 WaitHandle 数组,包含当前实例将等待的对象。

millisecondsTimeout
Int32

等待的毫秒数,或为 Infinite (-1),表示无限期等待。

返回

满足等待的对象的数组索引;如果没有任何对象满足等待,并且等效于 WaitTimeout 的时间间隔已过,则为 millisecondsTimeout

例外

waitHandles 参数为 null

- 或 -

waitHandles 数组中一个或多个对象为 null

waitHandles 中的对象数大于系统允许的数量。

millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。

等待结束,因为线程在未释放互斥的情况下退出。

waitHandles 是一个不含任何元素的数组。

waitHandles 数组包含其他应用程序域中 WaitHandle 的透明代理。

注解

如果 millisecondsTimeout 为零,则 方法不会阻止。 它测试等待句柄的状态并立即返回。

仅当等待由于放弃的互斥体而完成时,方法 WaitAny 才会引发 AbandonedMutexException 。 如果 waitHandles 包含的已释放互斥体具有比放弃的互斥体低的索引号,则 WaitAny 该方法将正常完成,并且不会引发异常。

此方法在等待终止时返回,无论何时发出任何句柄的信号或发生超时。 如果在调用期间发出多个对象的信号,则返回值是信号对象的数组索引,其索引值是所有信号对象的最小索引值。

等待句柄的最大数目为 64;如果当前线程处于 STA 状态,则为 63。

调用此方法重载与调用WaitAny(WaitHandle[], Int32, Boolean)重载和为 exitContext指定 false 相同。

适用于

.NET 9 和其他版本
产品 版本
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

WaitAny(WaitHandle[], TimeSpan)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

等待指定数组中的任意元素接收信号,同时使用 TimeSpan 指定时间间隔。

public static int WaitAny (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout);

参数

waitHandles
WaitHandle[]

一个 WaitHandle 数组,包含当前实例将等待的对象。

timeout
TimeSpan

表示等待毫秒数的 TimeSpan,或表示 -1 毫秒(无限期等待)的 TimeSpan

返回

满足等待的对象的数组索引;如果没有任何对象满足等待,并且等效于 WaitTimeout 的时间间隔已过,则为 timeout

例外

waitHandles 参数为 null

- 或 -

waitHandles 数组中一个或多个对象为 null

waitHandles 中的对象数大于系统允许的数量。

timeout 为 -1 毫秒以外的负数,表示无限期超时。

- 或 -

timeout 大于 Int32.MaxValue

等待结束,因为线程在未释放互斥的情况下退出。

waitHandles 是一个不含任何元素的数组。

waitHandles 数组包含其他应用程序域中 WaitHandle 的透明代理。

注解

如果 timeout 为零,则 方法不会阻止。 它测试等待句柄的状态并立即返回。

仅当等待由于放弃的互斥体而完成时,方法 WaitAny 才会引发 AbandonedMutexException 。 如果 waitHandles 包含的已释放互斥体具有比放弃的互斥体低的索引号,则 WaitAny 该方法将正常完成,并且不会引发异常。

此方法在等待终止时返回,无论是发出任何句柄的信号还是发生超时时。 如果在调用期间发出多个对象的信号,则返回值是信号对象的数组索引,其索引值是所有信号对象的最小索引值。

等待句柄的最大数目为 64;如果当前线程处于 STA 状态,则为 63。

timeout 最大值为 Int32.MaxValue

调用此方法重载与调用WaitAny(WaitHandle[], TimeSpan, Boolean)重载和为 exitContext指定 false 相同。

适用于

.NET 9 和其他版本
产品 版本
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

WaitAny(WaitHandle[], Int32, Boolean)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

等待指定数组中的任一元素收到信号,使用 32 位带符号整数指定时间间隔并指定是否在等待之前退出同步域。

public static int WaitAny (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext);

参数

waitHandles
WaitHandle[]

一个 WaitHandle 数组,包含当前实例将等待的对象。

millisecondsTimeout
Int32

等待的毫秒数,或为 Infinite (-1),表示无限期等待。

exitContext
Boolean

如果等待之前先退出上下文的同步域(如果在同步上下文中),并在稍后重新获取它,则为 true;否则为 false

返回

满足等待的对象的数组索引;如果没有任何对象满足等待,并且等效于 WaitTimeout 的时间间隔已过,则为 millisecondsTimeout

例外

waitHandles 参数为 null

- 或 -

waitHandles 数组中一个或多个对象为 null

waitHandles 中的对象数大于系统允许的数量。

waitHandles 是不含元素的数组,并且 .NET Framework 的版本为 1.0 或 1.1。

millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。

等待结束,因为线程在未释放互斥的情况下退出。

waitHandles 是不含元素的数组,并且 .NET Framework 的版本为 2.0 或更高。

waitHandles 数组包含其他应用程序域中 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();
        }
    }
}

注解

如果 millisecondsTimeout 为零,则 方法不会阻止。 它测试等待句柄的状态并立即返回。

仅当等待由于放弃的互斥体而完成时,方法 WaitAny 才会引发 AbandonedMutexException 。 如果 waitHandles 包含的已释放互斥体具有比放弃的互斥体低的索引号,则 WaitAny 该方法将正常完成,并且不会引发异常。 放弃的互斥体通常表示存在严重的编码错误。 对于系统范围的互斥,它可能表示应用程序已突然终止 (,例如,使用 Windows 任务管理器) 。 异常包含对调试有用的信息。

此方法在等待终止时返回,无论何时发出任何句柄的信号或发生超时。 如果在调用期间发出多个对象的信号,则返回值是信号对象的数组索引,其索引值是所有信号对象的最小索引值。

等待句柄的最大数目为 64;如果当前线程处于 STA 状态,则为 63。

退出上下文

除非 exitContext 从非默认托管上下文中调用此方法,否则 参数不起作用。 如果线程位于对派生自 ContextBoundObject的类实例的调用中,则托管上下文可能是非默认的。 即使当前正在对不是派生自 ContextBoundObject的类(如 ) String执行方法,也可以位于非默认上下文中( ContextBoundObject 如果 位于当前应用程序域的堆栈上)。

当代码在非默认上下文中执行时,将 指定 为 trueexitContext 会使线程退出非默认托管上下文 (即在执行此方法之前转换为默认上下文) 。 对此方法的调用完成后,线程将返回到原始的非默认上下文。

当上下文绑定类具有 属性时, SynchronizationAttribute 退出上下文可能很有用。 在这种情况下,将自动同步对 类成员的所有调用,并且同步域是类的整个代码主体。 如果成员的调用堆栈中的代码调用此方法并为 指定 trueexitContext,则线程将退出同步域,从而允许在调用 对象的任何成员时被阻止的线程继续。 此方法返回时,进行调用的线程必须等待重新进入同步域。

适用于

.NET 9 和其他版本
产品 版本
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1

WaitAny(WaitHandle[], TimeSpan, Boolean)

Source:
WaitHandle.cs
Source:
WaitHandle.cs
Source:
WaitHandle.cs

等待指定数组中的任一元素收到信号,使用 TimeSpan 指定时间间隔并指定是否在等待之前退出同步域。

public static int WaitAny (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext);

参数

waitHandles
WaitHandle[]

一个 WaitHandle 数组,包含当前实例将等待的对象。

timeout
TimeSpan

表示等待毫秒数的 TimeSpan,或表示 -1 毫秒(无限期等待)的 TimeSpan

exitContext
Boolean

如果等待之前先退出上下文的同步域(如果在同步上下文中),并在稍后重新获取它,则为 true;否则为 false

返回

满足等待的对象的数组索引;如果没有任何对象满足等待,并且等效于 WaitTimeout 的时间间隔已过,则为 timeout

例外

waitHandles 参数为 null

- 或 -

waitHandles 数组中一个或多个对象为 null

waitHandles 中的对象数大于系统允许的数量。

waitHandles 是不含元素的数组,并且 .NET Framework 的版本为 1.0 或 1.1。

timeout 为 -1 毫秒以外的负数,表示无限期超时。

- 或 -

timeout 大于 Int32.MaxValue

等待结束,因为线程在未释放互斥的情况下退出。

waitHandles 是不含元素的数组,并且 .NET Framework 的版本为 2.0 或更高。

waitHandles 数组包含其他应用程序域中 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();
        }
    }
}

注解

如果 timeout 为零,则 方法不会阻止。 它测试等待句柄的状态并立即返回。

仅当等待由于放弃的互斥体而完成时,方法 WaitAny 才会引发 AbandonedMutexException 。 如果 waitHandles 包含的已释放互斥体具有比放弃的互斥体低的索引号,则 WaitAny 该方法将正常完成,并且不会引发异常。 放弃的互斥体通常表示存在严重的编码错误。 对于系统范围的互斥,它可能表示应用程序已突然终止 (,例如,使用 Windows 任务管理器) 。 异常包含对调试有用的信息。

此方法在等待终止时返回,无论是发出任何句柄的信号还是发生超时时。 如果在调用期间发出多个对象的信号,则返回值是信号对象的数组索引,其索引值是所有信号对象的最小索引值。

等待句柄的最大数目为 64;如果当前线程处于 STA 状态,则为 63。

timeout 最大值为 Int32.MaxValue

退出上下文

除非 exitContext 从非默认托管上下文中调用此方法,否则 参数不起作用。 如果线程位于对派生自 ContextBoundObject的类实例的调用中,则托管上下文可能是非默认的。 即使当前正在对不是派生自 ContextBoundObject的类(如 ) String执行方法,也可以位于非默认上下文中( ContextBoundObject 如果 位于当前应用程序域的堆栈上)。

当代码在非默认上下文中执行时,将 指定 为 trueexitContext 会使线程退出非默认托管上下文 (即在执行此方法之前转换为默认上下文) 。 对此方法的调用完成后,线程将返回到原始的非默认上下文。

当上下文绑定类具有 属性时, SynchronizationAttribute 退出上下文可能很有用。 在这种情况下,将自动同步对 类成员的所有调用,并且同步域是类的整个代码主体。 如果成员的调用堆栈中的代码调用此方法并为 指定 trueexitContext,则线程将退出同步域,从而允许在调用 对象的任何成员时被阻止的线程继续。 此方法返回时,进行调用的线程必须等待重新进入同步域。

适用于

.NET 9 和其他版本
产品 版本
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1