WaitHandle.WaitAll 方法   
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
等待指定数组中的所有元素都收到信号。
重载
| 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(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 -> boolPublic Shared Function WaitAll (waitHandles As WaitHandle(), timeout As TimeSpan, exitContext As Boolean) As Boolean参数
- waitHandles
- WaitHandle[]
一个 WaitHandle 数组,包含当前实例将等待的对象。 此数组不能包含对同一对象的多个引用。
- exitContext
- Boolean
如果等待之前先退出上下文的同步域(如果在同步上下文中),并在稍后重新获取它,则为 true;否则为 false。
返回
如果 waitHandles 中的每个元素都收到信号,则为 true;否则为 false。
例外
              waitHandles 参数为 null。
- 或 -
              waitHandles 数组中一个或多个对象为 null。
- 或 -
              waitHandles 为不具有元素的数组且 .NET Framework 版本为 2.0 或更高版本。
              waitHandles 数组包含重复的元素。
              waitHandles 数组不含任何元素,并且 .NET Framework 版本为 1.0 或 1.1。
等待终止,因为线程在未释放互斥的情况下退出。
              waitHandles 数组包含其他应用程序域中 WaitHandle 的透明代理。
示例
下面的代码示例演示如何使用线程池异步创建和写入一组文件。 每个写入操作作为工作项排队,并在完成时发出信号。 主线程等待所有项发出信号,然后退出。
using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;
// Maintain state to pass to WriteToFile.
ref class State
{
public:
   String^ fileName;
   array<Byte>^byteArray;
   ManualResetEvent^ manualEvent;
   State( String^ fileName, array<Byte>^byteArray, ManualResetEvent^ manualEvent )
      : fileName( fileName ), byteArray( byteArray ), manualEvent( manualEvent )
   {}
};
ref class Writer
{
private:
   static int workItemCount = 0;
   Writer(){}
public:
   static void WriteToFile( Object^ state )
   {
      int workItemNumber = workItemCount;
      Interlocked::Increment( workItemCount );
      Console::WriteLine( "Starting work item {0}.", workItemNumber.ToString() );
      State^ stateInfo = dynamic_cast<State^>(state);
      FileStream^ fileWriter;
      
      // Create and write to the file.
      try
      {
         fileWriter = gcnew FileStream( stateInfo->fileName,FileMode::Create );
         fileWriter->Write( stateInfo->byteArray, 0, stateInfo->byteArray->Length );
      }
      finally
      {
         if ( fileWriter != nullptr )
         {
            fileWriter->Close();
         }
         
         // Signal main() that the work item has finished.
         Console::WriteLine( "Ending work item {0}.", workItemNumber.ToString() );
         stateInfo->manualEvent->Set();
      }
   }
};
int main()
{
   const int numberOfFiles = 5;
   String^ dirName =  "C:\\TestTest";
   String^ fileName;
   array<Byte>^byteArray;
   Random^ randomGenerator = gcnew Random;
   array<ManualResetEvent^>^manualEvents = gcnew array<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 = gcnew array<Byte>(1000000);
      randomGenerator->NextBytes( byteArray );
      manualEvents[ i ] = gcnew ManualResetEvent( false );
      stateInfo = gcnew State( fileName,byteArray,manualEvents[ i ] );
      ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &Writer::WriteToFile ), stateInfo );
   }
   
   // Since ThreadPool threads are background threads, 
   // wait for the work items to signal before exiting.
   if ( WaitHandle::WaitAll( manualEvents, TimeSpan(0,0,5), false ) )
   {
      Console::WriteLine( "Files written - main exiting." );
   }
   else
   {
      
      // The wait operation times out.
      Console::WriteLine( "Error writing files - main exiting." );
   }
}
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 个 NotSupportedException ,则会引发 。 如果数组包含重复项,则调用将失败。
的 timeout 最大值为 Int32.MaxValue。
退出上下文
除非 exitContext 从非默认托管上下文中调用此方法,否则 参数不起作用。 如果线程位于对派生自 ContextBoundObject的类实例的调用中,则托管上下文可能是非默认的。 即使当前正在对不是派生自 ContextBoundObject的类(如 ) String执行方法,也可以位于非默认上下文中( ContextBoundObject 如果 位于当前应用程序域的堆栈上)。
当代码在非默认上下文中执行时,将 指定 为 trueexitContext 会使线程退出非默认托管上下文 (即在执行此方法之前转换为默认上下文) 。 对此方法的调用完成后,线程将返回到原始的非默认上下文。
当上下文绑定类具有 属性时, SynchronizationAttribute 退出上下文可能很有用。 在这种情况下,将自动同步对 类成员的所有调用,并且同步域是类的整个代码主体。 如果成员的调用堆栈中的代码调用此方法并为 指定 trueexitContext,则线程将退出同步域,从而允许在调用 对象的任何成员时被阻止的线程继续。 此方法返回时,进行调用的线程必须等待重新进入同步域。
适用于
WaitAll(WaitHandle[], Int32, Boolean)
- 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 -> boolPublic Shared Function WaitAll (waitHandles As WaitHandle(), millisecondsTimeout As Integer, exitContext As Boolean) As Boolean参数
- waitHandles
- WaitHandle[]
一个 WaitHandle 数组,包含当前实例将等待的对象。 此数组不能包含对同一对象的多个引用(重复的元素)。
- exitContext
- Boolean
如果等待之前先退出上下文的同步域(如果在同步上下文中),并在稍后重新获取它,则为 true;否则为 false。
返回
如果 waitHandles 中的每个元素都已收到信号,则为 true;否则为 false。
例外
              waitHandles 参数为 null。
- 或 -
              waitHandles 数组中一个或多个对象为 null。
- 或 -
              waitHandles 为不具有元素的数组且 .NET Framework 版本为 2.0 或更高版本。
              waitHandles 数组包含重复的元素。
              waitHandles 数组不含任何元素,并且 .NET Framework 版本为 1.0 或 1.1。
              millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。
等待结束,因为线程在未释放互斥的情况下退出。
              waitHandles 数组包含其他应用程序域中 WaitHandle 的透明代理。
示例
下面的代码示例演示如何使用线程池异步创建和写入一组文件。 每个写入操作作为工作项排队,并在完成时发出信号。 主线程等待所有项发出信号,然后退出。
using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;
// Maintain state to pass to WriteToFile.
ref class State
{
public:
   String^ fileName;
   array<Byte>^byteArray;
   ManualResetEvent^ manualEvent;
   State( String^ fileName, array<Byte>^byteArray, ManualResetEvent^ manualEvent )
      : fileName( fileName ), byteArray( byteArray ), manualEvent( manualEvent )
   {}
};
ref class Writer
{
private:
   static int workItemCount = 0;
   Writer(){}
public:
   static void WriteToFile( Object^ state )
   {
      int workItemNumber = workItemCount;
      Interlocked::Increment( workItemCount );
      Console::WriteLine( "Starting work item {0}.", workItemNumber.ToString() );
      State^ stateInfo = dynamic_cast<State^>(state);
      FileStream^ fileWriter;
      
      // Create and write to the file.
      try
      {
         fileWriter = gcnew FileStream( stateInfo->fileName,FileMode::Create );
         fileWriter->Write( stateInfo->byteArray, 0, stateInfo->byteArray->Length );
      }
      finally
      {
         if ( fileWriter != nullptr )
         {
            fileWriter->Close();
         }
         
         // Signal main() that the work item has finished.
         Console::WriteLine( "Ending work item {0}.", workItemNumber.ToString() );
         stateInfo->manualEvent->Set();
      }
   }
};
int main()
{
   const int numberOfFiles = 5;
   String^ dirName =  "C:\\TestTest";
   String^ fileName;
   array<Byte>^byteArray;
   Random^ randomGenerator = gcnew Random;
   array<ManualResetEvent^>^manualEvents = gcnew array<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 = gcnew array<Byte>(1000000);
      randomGenerator->NextBytes( byteArray );
      manualEvents[ i ] = gcnew ManualResetEvent( false );
      stateInfo = gcnew State( fileName,byteArray,manualEvents[ i ] );
      ThreadPool::QueueUserWorkItem( gcnew 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." );
   }
}
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 个 NotSupportedException ,则会引发 。 如果数组中存在重复项,则调用失败并显示 DuplicateWaitObjectException。
退出上下文
除非 exitContext 从非默认托管上下文中调用此方法,否则 参数不起作用。 如果线程位于对派生自 ContextBoundObject的类实例的调用中,则托管上下文可能是非默认的。 即使当前正在对不是派生自 ContextBoundObject的类(如 ) String执行方法,也可以位于非默认上下文中( ContextBoundObject 如果 位于当前应用程序域的堆栈上)。
当代码在非默认上下文中执行时,将 指定 为 trueexitContext 会使线程退出非默认托管上下文 (即在执行此方法之前转换为默认上下文) 。 对此方法的调用完成后,线程将返回到原始的非默认上下文。
当上下文绑定类具有 属性时, SynchronizationAttribute 退出上下文可能很有用。 在这种情况下,将自动同步对 类成员的所有调用,并且同步域是类的整个代码主体。 如果成员的调用堆栈中的代码调用此方法并为 指定 trueexitContext,则线程将退出同步域,从而允许在调用 对象的任何成员时被阻止的线程继续。 此方法返回时,进行调用的线程必须等待重新进入同步域。
适用于
WaitAll(WaitHandle[], TimeSpan)
- 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 -> boolPublic Shared Function WaitAll (waitHandles As WaitHandle(), timeout As TimeSpan) As Boolean参数
- waitHandles
- WaitHandle[]
一个 WaitHandle 数组,包含当前实例将等待的对象。 此数组不能包含对同一对象的多个引用。
返回
如果 waitHandles 中的每个元素都已收到信号,则为 true;否则为 false。
例外
              waitHandles 参数为 null。
- 或 -
              waitHandles 数组中一个或多个对象为 null。
- 或 -
              waitHandles 是一个不含任何元素的数组。
              waitHandles 数组包含重复的元素。
注意:在适用于 Windows 应用商店应用的 .NET 或可移植类库中,改为捕获基类异常 ArgumentException。
等待终止,因为线程在未释放互斥的情况下退出。
              waitHandles 数组包含其他应用程序域中 WaitHandle 的透明代理。
注解
如果 timeout 为零,则该方法不会阻止。 它测试等待句柄的状态并立即返回。
方法 WaitAll 在等待终止时返回,这意味着所有句柄都已发出信号或发生超时。 如果传递的句柄超过 64 个 NotSupportedException ,则会引发 。 如果数组包含重复项,则调用将失败。
的 timeout 最大值为 Int32.MaxValue。
调用此方法重载与调用 WaitAll(WaitHandle[], TimeSpan, Boolean) 重载并为 指定falseexitContext相同。
适用于
WaitAll(WaitHandle[], Int32)
- 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 -> boolPublic Shared Function WaitAll (waitHandles As WaitHandle(), millisecondsTimeout As Integer) As Boolean参数
- waitHandles
- WaitHandle[]
一个 WaitHandle 数组,包含当前实例将等待的对象。 此数组不能包含对同一对象的多个引用(重复的元素)。
返回
如果 waitHandles 中的每个元素都已收到信号,则为 true;否则为 false。
例外
              waitHandles 参数为 null。
- 或 -
              waitHandles 数组中一个或多个对象为 null。
- 或 -
              waitHandles 是一个不含任何元素的数组。
              waitHandles 数组包含重复的元素。
注意:在适用于 Windows 应用商店应用的 .NET 或可移植类库中,改为捕获基类异常 ArgumentException。
              millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。
等待结束,因为线程在未释放互斥的情况下退出。
              waitHandles 数组包含其他应用程序域中 WaitHandle 的透明代理。
注解
如果 millisecondsTimeout 为零,则该方法不会阻止。 它测试等待句柄的状态并立即返回。
方法 WaitAll 在等待终止时返回,这意味着在发出所有句柄信号时或发生超时时返回。 如果传递的句柄超过 64 个 NotSupportedException ,则会引发 。 如果数组中存在重复项,调用将失败并出现 DuplicateWaitObjectException。
调用此方法重载与调用 WaitAll(WaitHandle[], Int32, Boolean) 重载并为 指定falseexitContext相同。
适用于
WaitAll(WaitHandle[])
- 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[] -> boolPublic Shared Function WaitAll (waitHandles As WaitHandle()) As Boolean参数
- waitHandles
- WaitHandle[]
一个 WaitHandle 数组,包含当前实例将等待的对象。 此数组不能包含对同一对象的多个引用。
返回
如果 true 中的每个元素都收到信号,则返回 waitHandles;否则该方法永不返回。
例外
              waitHandles 参数为 null。 - 或 -
              waitHandles 数组中一个或多个对象为 null。
- 或 -
              waitHandles 为不具有元素的数组且 .NET Framework 版本为 2.0 或更高版本。
              waitHandles 数组包含重复的元素。
注意:在适用于 Windows 应用商店应用的 .NET 或可移植类库中,改为捕获基类异常 ArgumentException。
              waitHandles 数组不含任何元素,并且 .NET Framework 版本为 1.0 或 1.1。
等待终止,因为线程在未释放互斥的情况下退出。
              waitHandles 数组包含其他应用程序域中 WaitHandle 的透明代理。
示例
下面的代码示例演示如何使用线程池异步创建和写入一组文件。 每个写入操作作为工作项排队,并在完成时发出信号。 主线程等待所有项发出信号,然后退出。
using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;
ref class State
{
public:
   String^ fileName;
   array<Byte>^byteArray;
   ManualResetEvent^ manualEvent;
   State( String^ fileName, array<Byte>^byteArray, ManualResetEvent^ manualEvent )
      : fileName( fileName ), byteArray( byteArray ), manualEvent( manualEvent )
   {}
};
ref class Writer
{
private:
   static int workItemCount = 0;
   Writer(){}
public:
   static void WriteToFile( Object^ state )
   {
      int workItemNumber = workItemCount;
      Interlocked::Increment( workItemCount );
      Console::WriteLine( "Starting work item {0}.", workItemNumber.ToString() );
      State^ stateInfo = dynamic_cast<State^>(state);
      FileStream^ fileWriter;
      
      // Create and write to the file.
      try
      {
         fileWriter = gcnew FileStream( stateInfo->fileName,FileMode::Create );
         fileWriter->Write( stateInfo->byteArray, 0, stateInfo->byteArray->Length );
      }
      finally
      {
         if ( fileWriter != nullptr )
         {
            fileWriter->Close();
         }
         
         // Signal main() that the work item has finished.
         Console::WriteLine( "Ending work item {0}.", workItemNumber.ToString() );
         stateInfo->manualEvent->Set();
      }
   }
};
void main()
{
   const int numberOfFiles = 5;
   String^ dirName =  "C:\\TestTest";
   String^ fileName;
   array<Byte>^byteArray;
   Random^ randomGenerator = gcnew Random;
   array<ManualResetEvent^>^manualEvents = gcnew array<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 = gcnew array<Byte>(1000000);
      randomGenerator->NextBytes( byteArray );
      manualEvents[ i ] = gcnew ManualResetEvent( false );
      stateInfo = gcnew State( fileName,byteArray,manualEvents[ i ] );
      ThreadPool::QueueUserWorkItem( gcnew 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." );
}
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 版中的新增功能。 在以前的版本中, WaitAll 方法在 true 放弃互斥体时返回 。 放弃的互斥通常表示存在严重的编码错误。 对于系统范围的互斥体,这可能指示应用程序已突然终止,例如,使用 Windows 任务管理器)  (。 异常包含对调试有用的信息。
当发出所有句柄的信号时,方法 WaitAll 返回 。 如果传递的句柄超过 64 个 NotSupportedException ,则会引发 。 如果数组包含重复项,调用将失败并出现 DuplicateWaitObjectException。
调用此方法重载等效于调用WaitAll(WaitHandle[], Int32, Boolean)方法重载并为 和 trueexitContext指定 -1 (或 Timeout.Infinite) millisecondsTimeout。