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
Source:
WaitHandle.cs
Source:
WaitHandle.cs

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

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

参数

waitHandles
WaitHandle[]

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

timeout
TimeSpan

一个 TimeSpan 表示等待的毫秒数,或 TimeSpan 表示要无限期等待的 -1 毫秒数。

exitContext
Boolean

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

返回

如果每个元素都收到信号,则为 />;否则为

例外

参数 waitHandlesnull.

-或-

数组中的 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();
        }
    }
}
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading

Public Class Test

    ' WaitHandle.WaitAll requires a multithreaded apartment 
    ' when using multiple wait handles.
    <MTAThreadAttribute> _
    Shared Sub Main()
        Const numberOfFiles As Integer = 5
        Dim dirName As String = "C:\TestTest"
        Dim fileName As String 

        Dim byteArray() As Byte 
        Dim randomGenerator As New Random()

        Dim manualEvents(numberOfFiles - 1) As ManualResetEvent
        Dim stateInfo As State 

        If Directory.Exists(dirName) <> True Then
            Directory.CreateDirectory(dirName)
        End If

        ' Queue the work items that create and write to the files.
        For i As Integer = 0 To numberOfFiles - 1
            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(AddressOf _
                Writer.WriteToFile, stateInfo)
        Next i
    
        ' 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) = True  Then

            Console.WriteLine("Files written - main exiting.")
        Else
        
            ' The wait operation times out.
            Console.WriteLine("Error writing files - main exiting.")
        End If
    End Sub

End Class
 
' Maintain state to pass to WriteToFile.
Public Class State

    Public fileName As String
    Public byteArray As Byte()
    Public manualEvent As ManualResetEvent

    Sub New(fileName As String, byteArray() As Byte, _
        manualEvent As ManualResetEvent)
    
        Me.fileName = fileName
        Me.byteArray = byteArray
        Me.manualEvent = manualEvent
    End Sub

End Class

Public Class Writer

    Private Sub New()
    End Sub

    Shared workItemCount As Integer = 0

    Shared Sub WriteToFile(state As Object)
        Dim workItemNumber As Integer = workItemCount
        Interlocked.Increment(workItemCount)
        Console.WriteLine("Starting work item {0}.", _
            workItemNumber.ToString())
        Dim stateInfo As State = CType(state, State)
        Dim fileWriter As FileStream = Nothing

        ' Create and write to the file.
        Try
            fileWriter = New FileStream( _
                stateInfo.fileName, FileMode.Create)
            fileWriter.Write(stateInfo.byteArray, _
                0, stateInfo.byteArray.Length)
        Finally
            If Not fileWriter Is Nothing Then
                fileWriter.Close()
            End If

            ' Signal Main that the work item has finished.
            Console.WriteLine("Ending work item {0}.", _
                workItemNumber.ToString())
            stateInfo.manualEvent.Set()
        End Try
    End Sub

End Class

注解

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

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

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

注释

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

的最大值 timeoutInt32.MaxValue.

退出上下文

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

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

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

适用于

WaitAll(WaitHandle[], Int32, Boolean)

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

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

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

参数

waitHandles
WaitHandle[]

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

millisecondsTimeout
Int32

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

exitContext
Boolean

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

返回

如果每个元素都收到信号,则为 />;否则为

例外

参数 waitHandlesnull.

-或-

数组中的 waitHandles 一个或多个对象是 null

-或-

waitHandles 是一个没有元素的数组,.NET Framework 版本为 2.0 或更高版本。

数组 waitHandles 包含重复的元素。

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

-或-

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

waitHandles 是一个没有元素的数组,.NET Framework 版本为 1.0 或 1.1。

millisecondsTimeout 是非 -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();
        }
    }
}
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading

Public Class Test

    ' WaitHandle.WaitAll requires a multithreaded apartment 
    ' when using multiple wait handles.
    <MTAThreadAttribute> _
    Shared Sub Main()
        Const numberOfFiles As Integer = 5
        Dim dirName As String = "C:\TestTest"
        Dim fileName As String 

        Dim byteArray() As Byte 
        Dim randomGenerator As New Random()

        Dim manualEvents(numberOfFiles - 1) As ManualResetEvent
        Dim stateInfo As State 

        If Directory.Exists(dirName) <> True Then
            Directory.CreateDirectory(dirName)
        End If

        ' Queue the work items that create and write to the files.
        For i As Integer = 0 To numberOfFiles - 1
            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(AddressOf _
                Writer.WriteToFile, stateInfo)
        Next i
    
        ' Since ThreadPool threads are background threads, 
        ' wait for the work items to signal before exiting.
        If WaitHandle.WaitAll(manualEvents, 5000, false) = True  Then

            Console.WriteLine("Files written - main exiting.")
        Else
        
            ' The wait operation times out.
            Console.WriteLine("Error writing files - main exiting.")
        End If
    End Sub

End Class
 
' Maintain state to pass to WriteToFile.
Public Class State

    Public fileName As String
    Public byteArray As Byte()
    Public manualEvent As ManualResetEvent

    Sub New(fileName As String, byteArray() As Byte, _
        manualEvent As ManualResetEvent)
    
        Me.fileName = fileName
        Me.byteArray = byteArray
        Me.manualEvent = manualEvent
    End Sub

End Class

Public Class Writer

    Private Sub New()
    End Sub

    Shared workItemCount As Integer = 0

    Shared Sub WriteToFile(state As Object)
        Dim workItemNumber As Integer = workItemCount
        Interlocked.Increment(workItemCount)
        Console.WriteLine("Starting work item {0}.", _
            workItemNumber.ToString())
        Dim stateInfo As State = CType(state, State)
        Dim fileWriter As FileStream = Nothing

        ' Create and write to the file.
        Try
            fileWriter = New FileStream( _
                stateInfo.fileName, FileMode.Create)
            fileWriter.Write(stateInfo.byteArray, _
                0, stateInfo.byteArray.Length)
        Finally
            If Not fileWriter Is Nothing Then
                fileWriter.Close()
            End If

            ' Signal Main that the work item has finished.
            Console.WriteLine("Ending work item {0}.", _
                workItemNumber.ToString())
            stateInfo.manualEvent.Set()
        End Try
    End Sub

End Class

注解

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

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

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

注释

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

退出上下文

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

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

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

适用于

WaitAll(WaitHandle[], TimeSpan)

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

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

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

参数

waitHandles
WaitHandle[]

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

timeout
TimeSpan

一个 TimeSpan 表示等待的毫秒数,或 TimeSpan 表示要无限期等待的 -1 毫秒数。

返回

如果每个元素都收到信号,则为 />;否则为

例外

参数 waitHandlesnull.

-或-

数组中的 waitHandles 一个或多个对象是 null

-或-

waitHandles 是一个没有元素的数组。

数组 waitHandles 包含重复的元素。

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

-或-

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

timeout 是一个负数,而不是 -1 毫秒,表示无限超时。

-或-

timeout 大于 Int32.MaxValue

等待已终止,因为线程退出而不释放互斥体。

waitHandles 数组包含另一个应用程序域中的 WaitHandle 透明代理。

注解

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

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

注释

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

的最大值 timeoutInt32.MaxValue.

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

适用于

WaitAll(WaitHandle[], Int32)

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

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

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

参数

waitHandles
WaitHandle[]

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

millisecondsTimeout
Int32

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

返回

如果每个元素都收到信号,则为 />;否则为

例外

参数 waitHandlesnull.

-或-

数组中的 waitHandles 一个或多个对象是 null

-或-

waitHandles 是一个没有元素的数组。

数组 waitHandles 包含重复的元素。

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

-或-

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

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

等待已完成,因为线程退出而不释放互斥体。

waitHandles 数组包含另一个应用程序域中的 WaitHandle 透明代理。

注解

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

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

注释

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

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

适用于

WaitAll(WaitHandle[])

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

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

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

参数

waitHandles
WaitHandle[]

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

返回

true 当每个元素 waitHandles 都收到信号时,否则该方法永远不会返回。

例外

参数 waitHandlesnull. -或-

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

-或-

waitHandles 是一个没有元素的数组,.NET Framework 版本为 2.0 或更高版本。

数组 waitHandles 包含重复的元素。

中的 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();
        }
    }
}
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading

Public Class Test

    ' WaitHandle.WaitAll requires a multithreaded apartment 
    ' when using multiple wait handles.
    <MTAThreadAttribute> _
    Shared Sub Main()
        Const numberOfFiles As Integer = 5
        Dim dirName As String = "C:\TestTest"
        Dim fileName As String 

        Dim byteArray() As Byte 
        Dim randomGenerator As New Random()

        Dim manualEvents(numberOfFiles - 1) As ManualResetEvent
        Dim stateInfo As State 

        If Directory.Exists(dirName) <> True Then
            Directory.CreateDirectory(dirName)
        End If

        ' Queue the work items that create and write to the files.
        For i As Integer = 0 To numberOfFiles - 1
            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(AddressOf _
                Writer.WriteToFile, stateInfo)
        Next i
    
        ' Since ThreadPool threads are background threads, 
        ' wait for the work items to signal before exiting.
        WaitHandle.WaitAll(manualEvents)
        Console.WriteLine("Files written - main exiting.")
    End Sub

End Class
 
' Maintain state to pass to WriteToFile.
Public Class State

    Public fileName As String
    Public byteArray As Byte()
    Public manualEvent As ManualResetEvent

    Sub New(fileName As String, byteArray() As Byte, _
        manualEvent As ManualResetEvent)
    
        Me.fileName = fileName
        Me.byteArray = byteArray
        Me.manualEvent = manualEvent
    End Sub

End Class

Public Class Writer

    Private Sub New()
    End Sub

    Shared workItemCount As Integer = 0

    Shared Sub WriteToFile(state As Object)
        Dim workItemNumber As Integer = workItemCount
        Interlocked.Increment(workItemCount)
        Console.WriteLine("Starting work item {0}.", _
            workItemNumber.ToString())
        Dim stateInfo As State = CType(state, State)
        Dim fileWriter As FileStream = Nothing

        ' Create and write to the file.
        Try
            fileWriter = New FileStream( _
                stateInfo.fileName, FileMode.Create)
            fileWriter.Write(stateInfo.byteArray, _
                0, stateInfo.byteArray.Length)
        Finally
            If Not fileWriter Is Nothing Then
                fileWriter.Close()
            End If

            ' Signal Main that the work item has finished.
            Console.WriteLine("Ending work item {0}.", _
                workItemNumber.ToString())
            stateInfo.manualEvent.Set()
        End Try
    End Sub

End Class

注解

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

当发出所有句柄的信号时,该方法 WaitAll 将返回。 如果传递了 64 个以上的句柄,则会引发 a NotSupportedException 。 如果数组包含重复项,则调用失败并显示一个 DuplicateWaitObjectException

注释

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

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

适用于