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)

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

傳回

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

由於執行緒結束時未釋放 Mutex,已結束等候。

waitHandles 陣列在另一個應用程式定義域中包含 WaitHandle 的 Transparent Proxy。

範例

下列程式代碼範例示範如何使用線程集區,以異步方式建立和寫入檔案群組。 每個寫入作業都會排入佇列作為工作專案,並在完成時發出訊號。 主線程會等候所有專案發出訊號,然後結束。

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 為零,則方法不會封鎖。 它會測試等候句柄的狀態,並立即傳回。

如果放棄 mutex, AbandonedMutexException 則會擲回 。 已放棄的 Mutex 通常表示嚴重的程式代碼撰寫錯誤。 在全系統 Mutex 的情況下,它可能表示應用程式已突然終止 (例如,使用 Windows 任務管理員) 。 例外狀況包含適用於偵錯的資訊。

方法 WaitAll 會在等候終止時傳回,這表示所有句柄都會發出訊號或發生逾時。 如果傳遞超過 64 個 NotSupportedException 句柄,則會擲回 。 如果陣列包含重複專案,呼叫將會失敗。

注意

WaitAll在處於狀態的STA線程上不支援 方法。

最大 timeout 值為 Int32.MaxValue

結束內容

exitContext除非從非預設 Managed 內容內呼叫這個方法,否則參數不會有任何作用。 如果您的線程位於衍生自 ContextBoundObject之類別實例的呼叫內,則Managed內容可以是非預設的。 即使您目前正在不是衍生自 ContextBoundObject的類別上執行方法,例如 String,如果 ContextBoundObject 位於目前應用程式域中的堆疊上,您也可以在非預設內容中。

當您的程式代碼在非預設內容中執行時,指定 trueexitContext 會導致線程結束非預設受控內容 (,也就是在執行此方法之前轉換至默認內容) 。 呼叫這個方法之後,線程會傳回原始的非預設內容。

當內容系結類別具有 SynchronizationAttribute 屬性時,結束內容可能會很有用。 在此情況下,類別成員的所有呼叫都會自動同步處理,而同步處理網域則是類別的整個程式代碼主體。 如果成員呼叫堆疊中的程式代碼呼叫這個方法並指定 trueexitContext,線程會結束同步處理網域,這允許在呼叫物件的任何成員時封鎖的線程繼續進行。 當這個方法傳回時,進行呼叫的線程必須等候重新進入同步處理網域。

適用於

WaitAll(WaitHandle[], Int32, Boolean)

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

傳回

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 以外的負數,表示無限逾時。

由於執行緒結束時未釋放 Mutex,已完成等候。

waitHandles 陣列在另一個應用程式定義域中包含 WaitHandle 的 Transparent Proxy。

範例

下列程式代碼範例示範如何使用線程集區,以異步方式建立和寫入檔案群組。 每個寫入作業都會排入佇列作為工作專案,並在完成時發出訊號。 主線程會等候所有專案發出訊號,然後結束。

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 為零,則方法不會封鎖。 它會測試等候句柄的狀態,並立即傳回。

如果放棄 mutex, AbandonedMutexException 則會擲回 。 已放棄的 Mutex 通常表示嚴重的程式代碼撰寫錯誤。 在全系統 Mutex 的情況下,它可能表示應用程式已突然終止 (例如,使用 Windows 任務管理員) 。 例外狀況包含適用於偵錯的資訊。

方法 WaitAll 會在等候終止時傳回,這表示當發出所有句柄的訊號或發生逾時時。 如果傳遞超過 64 個 NotSupportedException 句柄,則會擲回 。 如果陣列中有重複項目,呼叫會失敗並 DuplicateWaitObjectException出現 。

注意

WaitAll在處於狀態的STA線程上不支援 方法。

結束內容

exitContext除非從非預設 Managed 內容內呼叫這個方法,否則參數不會有任何作用。 如果您的線程位於衍生自 ContextBoundObject之類別實例的呼叫內,則Managed內容可以是非預設的。 即使您目前正在不是衍生自 ContextBoundObject的類別上執行方法,例如 String,如果 ContextBoundObject 位於目前應用程式域中的堆疊上,您也可以在非預設內容中。

當您的程式代碼在非預設內容中執行時,指定 trueexitContext 會導致線程結束非預設受控內容 (,也就是在執行此方法之前轉換至默認內容) 。 呼叫這個方法之後,線程會傳回原始的非預設內容。

當內容系結類別具有 SynchronizationAttribute 屬性時,結束內容可能會很有用。 在此情況下,類別成員的所有呼叫都會自動同步處理,而同步處理網域則是類別的整個程式代碼主體。 如果成員呼叫堆疊中的程式代碼呼叫這個方法並指定 trueexitContext,線程會結束同步處理網域,這允許在呼叫物件的任何成員時封鎖的線程繼續進行。 當這個方法傳回時,進行呼叫的線程必須等候重新進入同步處理網域。

適用於

WaitAll(WaitHandle[], TimeSpan)

來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
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 毫秒。

傳回

waitHandles 中的所有項目都收到信號時,則為 true;否則為 false

例外狀況

waitHandles 參數為 null

-或-

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

-或-

waitHandles 是不含任何項目的陣列。

waitHandles 陣列包含重複的項目。

注意:在適用於 Microsoft Store 的 .NET 應用程式可攜式類別庫中,請改為捕捉基底類別例外狀況 ArgumentException

waitHandles 中的物件數目超過系統允許的數目。

-或-

目前的執行緒是 STA 狀態,而 waitHandles 包含多個元素。

timeout 為 -1 毫秒以外的負數,表示無限逾時。

-或-

timeout 大於 Int32.MaxValue

由於執行緒結束時未釋放 Mutex,已結束等候。

waitHandles 陣列在另一個應用程式定義域中包含 WaitHandle 的 Transparent Proxy。

備註

如果 timeout 為零,則方法不會封鎖。 它會測試等候句柄的狀態,並立即傳回。

方法 WaitAll 會在等候終止時傳回,這表示所有句柄都會發出訊號或發生逾時。 如果傳遞超過 64 個 NotSupportedException 句柄,則會擲回 。 如果陣列包含重複專案,呼叫將會失敗。

注意

WaitAll在處於狀態的STA線程上不支援 方法。

最大 timeout 值為 Int32.MaxValue

呼叫這個方法多載與呼叫 WaitAll(WaitHandle[], TimeSpan, Boolean) 多載和針對 exitContext指定false相同。

適用於

WaitAll(WaitHandle[], Int32)

來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
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)。

傳回

waitHandles 中的所有項目都收到信號時,則為 true;否則為 false

例外狀況

waitHandles 參數為 null

-或-

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

-或-

waitHandles 是不含任何項目的陣列。

waitHandles 陣列包含重複的項目。

注意:在適用於 Microsoft Store 的 .NET 應用程式可攜式類別庫中,請改為捕捉基底類別例外狀況 ArgumentException

waitHandles 中的物件數目超過系統允許的數目。

-或-

目前的執行緒是 STA 狀態,而 waitHandles 包含多個元素。

millisecondsTimeout 為 -1 以外的負數,表示無限逾時。

由於執行緒結束時未釋放 Mutex,已完成等候。

waitHandles 陣列在另一個應用程式定義域中包含 WaitHandle 的 Transparent Proxy。

備註

如果 millisecondsTimeout 為零,則方法不會封鎖。 它會測試等候句柄的狀態,並立即傳回。

方法 WaitAll 會在等候終止時傳回,這表示當發出所有句柄的訊號或發生逾時時。 如果傳遞超過 64 個 NotSupportedException 句柄,則會擲回 。 如果陣列中有重複項目,呼叫會失敗並 DuplicateWaitObjectException出現 。

注意

WaitAll在處於狀態的STA線程上不支援 方法。

呼叫這個方法多載與呼叫 WaitAll(WaitHandle[], Int32, Boolean) 多載和針對 exitContext指定false相同。

適用於

WaitAll(WaitHandle[])

來源:
WaitHandle.cs
來源:
WaitHandle.cs
來源:
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 陣列,包含目前執行個體將等候的物件。 這個陣列不能包含相同物件的多個參考。

傳回

waitHandles 中的所有項目都收到信號時,則為 true;否則絕不會傳回這個方法。

例外狀況

waitHandles 參數為 null。 -或-

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

-或-

waitHandles 是沒有任何項目的陣列,且 .NET Framework 版本為 2.0 或更新版本。

waitHandles 陣列包含重複的項目。

注意:在適用於 Microsoft Store 的 .NET 應用程式可攜式類別庫中,請改為捕捉基底類別例外狀況 ArgumentException

waitHandles 中的物件數目超過系統允許的數目。

-或-

目前的執行緒是 STA 狀態,而 waitHandles 包含多個元素。

waitHandles 是沒有任何項目的陣列,且 .NET Framework 版本為 1.0 或 1.1。

由於執行緒結束時未釋放 Mutex,已結束等候。

waitHandles 陣列在另一個應用程式定義域中包含 WaitHandle 的 Transparent Proxy。

範例

下列程式代碼範例示範如何使用線程集區,以異步方式建立和寫入檔案群組。 每個寫入作業都會排入佇列作為工作專案,並在完成時發出訊號。 主線程會等候所有專案發出訊號,然後結束。

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 放棄 Mutex 時傳回。 已放棄的 Mutex 通常表示嚴重的程式代碼撰寫錯誤。 在全系統 Mutex 的情況下,它可能表示應用程式已突然終止 (例如,使用 Windows 任務管理員) 。 例外狀況包含適用於偵錯的資訊。

當發出所有句柄的訊號時,方法 WaitAll 會傳回 。 如果傳遞超過 64 個 NotSupportedException 句柄,則會擲回 。 如果陣列包含重複項目,呼叫會失敗並 DuplicateWaitObjectException出現 。

注意

WaitAll在處於狀態的STA線程上不支援 方法。

呼叫這個方法多載相當於呼叫 WaitAll(WaitHandle[], Int32, Boolean) 方法多載,併為 和 指定 -1 (或 Timeout.Infinite) millisecondsTimeouttrueexitContext

適用於