使用英语阅读

通过


WaitHandle.WaitAll 方法

定义

等待指定数组中的所有元素都收到信号。

重载

WaitAll(WaitHandle[], TimeSpan, Boolean)

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

WaitAll(WaitHandle[], Int32, Boolean)

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

WaitAll(WaitHandle[], TimeSpan)

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

WaitAll(WaitHandle[], Int32)

等待指定数组中的所有元素接收信号,同时使用 Int32 值指定时间间隔。

WaitAll(WaitHandle[])

等待指定数组中的所有元素都收到信号。

WaitAll(WaitHandle[], TimeSpan, Boolean)

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

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

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

参数

waitHandles
WaitHandle[]

一个 WaitHandle 数组,包含当前实例将等待的对象。 此数组不能包含对同一对象的多个引用。

timeout
TimeSpan

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

exitContext
Boolean

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

返回

如果 waitHandles 中的每个元素都收到信号,则为 true;否则为 false

例外

waitHandles 参数为 null

- 或 -

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

- 或 -

waitHandles 为不具有元素的数组且 .NET Framework 版本为 2.0 或更高版本。

waitHandles 数组包含重复的元素。

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

- 或 -

STAThreadAttribute 属性应用于当前线程的线程过程且 waitHandles 包含多个元素。

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

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

- 或 -

timeout 大于 Int32.MaxValue

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

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

示例

下面的代码示例演示如何使用线程池异步创建和写入一组文件。 每个写入操作作为工作项排队,并在完成时发出信号。 主线程等待所有项发出信号,然后退出。

using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;

class Test
{
    static void Main()
    {
        const int numberOfFiles = 5;
        string dirName = @"C:\TestTest";
        string fileName;

        byte[] byteArray;
        Random randomGenerator = new Random();

        ManualResetEvent[] manualEvents = 
            new ManualResetEvent[numberOfFiles];
        State stateInfo;

        if(!Directory.Exists(dirName))
        {
            Directory.CreateDirectory(dirName);
        }

        // Queue the work items that create and write to the files.
        for(int i = 0; i < numberOfFiles; i++)
        {
            fileName = string.Concat(
                dirName, @"\Test", i.ToString(), ".dat");

            // Create random data to write to the file.
            byteArray = new byte[1000000];
            randomGenerator.NextBytes(byteArray);

            manualEvents[i] = new ManualResetEvent(false);

            stateInfo = 
                new State(fileName, byteArray, manualEvents[i]);

            ThreadPool.QueueUserWorkItem(new WaitCallback(
                Writer.WriteToFile), stateInfo);
        }
    
        // Since ThreadPool threads are background threads, 
        // wait for the work items to signal before exiting.
        if(WaitHandle.WaitAll(
            manualEvents, new TimeSpan(0, 0, 5), false))
        {
            Console.WriteLine("Files written - main exiting.");
        }
        else
        {
            // The wait operation times out.
            Console.WriteLine("Error writing files - main exiting.");
        }
    }
}

// Maintain state to pass to WriteToFile.
class State
{
    public string fileName;
    public byte[] byteArray;
    public ManualResetEvent manualEvent;

    public State(string fileName, byte[] byteArray, 
        ManualResetEvent manualEvent)
    {
        this.fileName = fileName;
        this.byteArray = byteArray;
        this.manualEvent = manualEvent;
    }
}

class Writer
{
    static int workItemCount = 0;
    Writer() {}

    public static void WriteToFile(object state)
    {
        int workItemNumber = workItemCount;
        Interlocked.Increment(ref workItemCount);
        Console.WriteLine("Starting work item {0}.",
            workItemNumber.ToString());
        State stateInfo = (State)state;
        FileStream fileWriter = null;

        // Create and write to the file.
        try
        {
            fileWriter = new FileStream(
                stateInfo.fileName, FileMode.Create);
            fileWriter.Write(stateInfo.byteArray, 
                0, stateInfo.byteArray.Length);
        }
        finally
        {
            if(fileWriter != null)
            {
                fileWriter.Close();
            }

            // Signal Main that the work item has finished.
            Console.WriteLine("Ending work item {0}.", 
                workItemNumber.ToString());
            stateInfo.manualEvent.Set();
        }
    }
}

注解

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

如果放弃互斥体, AbandonedMutexException 则会引发 。 放弃的互斥体通常表示存在严重的编码错误。 对于系统范围的互斥,它可能表示应用程序已突然终止 (,例如,使用 Windows 任务管理器) 。 异常包含对调试有用的信息。

方法 WaitAll 在等待终止时返回,这意味着发出所有句柄的信号或发生超时。 如果传递的句柄超过 64 个 NotSupportedException ,则会引发 。 如果数组包含重复项,则调用将失败。

备注

WaitAll处于状态的线程STA不支持 方法。

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

WaitAll(WaitHandle[], Int32, Boolean)

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

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

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

参数

waitHandles
WaitHandle[]

一个 WaitHandle 数组,包含当前实例将等待的对象。 此数组不能包含对同一对象的多个引用(重复的元素)。

millisecondsTimeout
Int32

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

exitContext
Boolean

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

返回

如果 waitHandles 中的每个元素都已收到信号,则为 true;否则为 false

例外

waitHandles 参数为 null

- 或 -

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

- 或 -

waitHandles 为不具有元素的数组且 .NET Framework 版本为 2.0 或更高版本。

waitHandles 数组包含重复的元素。

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

- 或 -

当前线程处于 STA 状态,且 waitHandles 包含多个元素。

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

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

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

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

示例

下面的代码示例演示如何使用线程池异步创建和写入一组文件。 每个写入操作作为工作项排队,并在完成时发出信号。 主线程等待所有项发出信号,然后退出。

using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;

class Test
{
    static void Main()
    {
        const int numberOfFiles = 5;
        string dirName = @"C:\TestTest";
        string fileName;

        byte[] byteArray;
        Random randomGenerator = new Random();

        ManualResetEvent[] manualEvents = 
            new ManualResetEvent[numberOfFiles];
        State stateInfo;

        if(!Directory.Exists(dirName))
        {
            Directory.CreateDirectory(dirName);
        }

        // Queue the work items that create and write to the files.
        for(int i = 0; i < numberOfFiles; i++)
        {
            fileName = string.Concat(
                dirName, @"\Test", i.ToString(), ".dat");

            // Create random data to write to the file.
            byteArray = new byte[1000000];
            randomGenerator.NextBytes(byteArray);

            manualEvents[i] = new ManualResetEvent(false);

            stateInfo = 
                new State(fileName, byteArray, manualEvents[i]);

            ThreadPool.QueueUserWorkItem(new WaitCallback(
                Writer.WriteToFile), stateInfo);
        }
    
        // Since ThreadPool threads are background threads, 
        // wait for the work items to signal before exiting.
        if(WaitHandle.WaitAll(manualEvents, 5000, false))
        {
            Console.WriteLine("Files written - main exiting.");
        }
        else
        {
            // The wait operation times out.
            Console.WriteLine("Error writing files - main exiting.");
        }
    }
}

// Maintain state to pass to WriteToFile.
class State
{
    public string fileName;
    public byte[] byteArray;
    public ManualResetEvent manualEvent;

    public State(string fileName, byte[] byteArray, 
        ManualResetEvent manualEvent)
    {
        this.fileName = fileName;
        this.byteArray = byteArray;
        this.manualEvent = manualEvent;
    }
}

class Writer
{
    static int workItemCount = 0;
    Writer() {}

    public static void WriteToFile(object state)
    {
        int workItemNumber = workItemCount;
        Interlocked.Increment(ref workItemCount);
        Console.WriteLine("Starting work item {0}.",
            workItemNumber.ToString());
        State stateInfo = (State)state;
        FileStream fileWriter = null;

        // Create and write to the file.
        try
        {
            fileWriter = new FileStream(
                stateInfo.fileName, FileMode.Create);
            fileWriter.Write(stateInfo.byteArray, 
                0, stateInfo.byteArray.Length);
        }
        finally
        {
            if(fileWriter != null)
            {
                fileWriter.Close();
            }

            // Signal Main that the work item has finished.
            Console.WriteLine("Ending work item {0}.", 
                workItemNumber.ToString());
            stateInfo.manualEvent.Set();
        }
    }
}

注解

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

如果放弃互斥体, AbandonedMutexException 则会引发 。 放弃的互斥体通常表示存在严重的编码错误。 对于系统范围的互斥,它可能表示应用程序已突然终止 (,例如,使用 Windows 任务管理器) 。 异常包含对调试有用的信息。

方法 WaitAll 在等待终止时返回,这意味着当发出所有句柄的信号或发生超时时。 如果传递的句柄超过 64 个 NotSupportedException ,则会引发 。 如果数组中存在重复项,则调用失败并显示 DuplicateWaitObjectException

备注

WaitAll处于状态的线程STA不支持 方法。

退出上下文

除非 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

WaitAll(WaitHandle[], TimeSpan)

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

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

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

参数

waitHandles
WaitHandle[]

一个 WaitHandle 数组,包含当前实例将等待的对象。 此数组不能包含对同一对象的多个引用。

timeout
TimeSpan

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

返回

如果 waitHandles 中的每个元素都已收到信号,则为 true;否则为 false

例外

waitHandles 参数为 null

- 或 -

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

- 或 -

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

waitHandles 数组包含重复的元素。

注意:在适用于 Windows 应用商店应用的 .NET可移植类库中,改为捕获基类异常 ArgumentException

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

- 或 -

当前线程处于 STA 状态,且 waitHandles 包含多个元素。

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

- 或 -

timeout 大于 Int32.MaxValue

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

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

注解

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

方法 WaitAll 在等待终止时返回,这意味着所有句柄都已发出信号或发生超时。 如果传递的句柄超过 64 个 NotSupportedException ,则会引发 。 如果数组包含重复项,则调用将失败。

备注

WaitAll 处于 状态的线程 STA 上不支持 方法。

timeout 最大值为 Int32.MaxValue

调用此方法重载与调用 WaitAll(WaitHandle[], TimeSpan, Boolean) 重载并为 指定falseexitContext相同。

适用于

.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

WaitAll(WaitHandle[], Int32)

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

等待指定数组中的所有元素接收信号,同时使用 Int32 值指定时间间隔。

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

参数

waitHandles
WaitHandle[]

一个 WaitHandle 数组,包含当前实例将等待的对象。 此数组不能包含对同一对象的多个引用(重复的元素)。

millisecondsTimeout
Int32

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

返回

如果 waitHandles 中的每个元素都已收到信号,则为 true;否则为 false

例外

waitHandles 参数为 null

- 或 -

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

- 或 -

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

waitHandles 数组包含重复的元素。

注意:在适用于 Windows 应用商店应用的 .NET可移植类库中,改为捕获基类异常 ArgumentException

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

- 或 -

当前线程处于 STA 状态,且 waitHandles 包含多个元素。

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

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

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

注解

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

方法 WaitAll 在等待终止时返回,这意味着在发出所有句柄信号时或发生超时时返回。 如果传递的句柄超过 64 个 NotSupportedException ,则会引发 。 如果数组中存在重复项,调用将失败并出现 DuplicateWaitObjectException

备注

WaitAll 处于 状态的线程 STA 上不支持 方法。

调用此方法重载与调用 WaitAll(WaitHandle[], Int32, Boolean) 重载并为 指定falseexitContext相同。

适用于

.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

WaitAll(WaitHandle[])

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

等待指定数组中的所有元素都收到信号。

public static bool WaitAll (System.Threading.WaitHandle[] waitHandles);

参数

waitHandles
WaitHandle[]

一个 WaitHandle 数组,包含当前实例将等待的对象。 此数组不能包含对同一对象的多个引用。

返回

如果 true 中的每个元素都收到信号,则返回 waitHandles;否则该方法永不返回。

例外

waitHandles 参数为 null。 - 或 -

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

- 或 -

waitHandles 为不具有元素的数组且 .NET Framework 版本为 2.0 或更高版本。

waitHandles 数组包含重复的元素。

注意:在适用于 Windows 应用商店应用的 .NET可移植类库中,改为捕获基类异常 ArgumentException

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

- 或 -

当前线程处于 STA 状态,且 waitHandles 包含多个元素。

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

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

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

示例

下面的代码示例演示如何使用线程池异步创建和写入一组文件。 每个写入操作作为工作项排队,并在完成时发出信号。 主线程等待所有项发出信号,然后退出。

using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;

class Test
{
    static void Main()
    {
        const int numberOfFiles = 5;
        string dirName = @"C:\TestTest";
        string fileName;

        byte[] byteArray;
        Random randomGenerator = new Random();

        ManualResetEvent[] manualEvents = 
            new ManualResetEvent[numberOfFiles];
        State stateInfo;

        if(!Directory.Exists(dirName))
        {
            Directory.CreateDirectory(dirName);
        }

        // Queue the work items that create and write to the files.
        for(int i = 0; i < numberOfFiles; i++)
        {
            fileName = string.Concat(
                dirName, @"\Test", i.ToString(), ".dat");

            // Create random data to write to the file.
            byteArray = new byte[1000000];
            randomGenerator.NextBytes(byteArray);

            manualEvents[i] = new ManualResetEvent(false);

            stateInfo = 
                new State(fileName, byteArray, manualEvents[i]);

            ThreadPool.QueueUserWorkItem(new WaitCallback(
                Writer.WriteToFile), stateInfo);
        }
    
        // Since ThreadPool threads are background threads, 
        // wait for the work items to signal before exiting.
        WaitHandle.WaitAll(manualEvents);
        Console.WriteLine("Files written - main exiting.");
    }
}

// Maintain state to pass to WriteToFile.
class State
{
    public string fileName;
    public byte[] byteArray;
    public ManualResetEvent manualEvent;

    public State(string fileName, byte[] byteArray, 
        ManualResetEvent manualEvent)
    {
        this.fileName = fileName;
        this.byteArray = byteArray;
        this.manualEvent = manualEvent;
    }
}

class Writer
{
    static int workItemCount = 0;
    Writer() {}

    public static void WriteToFile(object state)
    {
        int workItemNumber = workItemCount;
        Interlocked.Increment(ref workItemCount);
        Console.WriteLine("Starting work item {0}.",
            workItemNumber.ToString());
        State stateInfo = (State)state;
        FileStream fileWriter = null;

        // Create and write to the file.
        try
        {
            fileWriter = new FileStream(
                stateInfo.fileName, FileMode.Create);
            fileWriter.Write(stateInfo.byteArray, 
                0, stateInfo.byteArray.Length);
        }
        finally
        {
            if(fileWriter != null)
            {
                fileWriter.Close();
            }

            // Signal Main that the work item has finished.
            Console.WriteLine("Ending work item {0}.", 
                workItemNumber.ToString());
            stateInfo.manualEvent.Set();
        }
    }
}

注解

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

当发出所有句柄的信号时,方法 WaitAll 返回 。 如果传递的句柄超过 64 个 NotSupportedException ,则会引发 。 如果数组包含重复项,调用将失败并出现 DuplicateWaitObjectException

备注

WaitAll 处于 状态的线程 STA 上不支持 方法。

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

适用于

.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