This documentation is archived and is not being maintained.

WaitHandle.WaitAll Method (WaitHandle[])

.NET Framework 1.1

Waits for all the elements in the specified array to receive a signal.

[Visual Basic]
Overloads Public Shared Function WaitAll( _
   ByVal waitHandles() As WaitHandle _
) As Boolean
[C#]
public static bool WaitAll(
 WaitHandle[] waitHandles
);
[C++]
public: static bool WaitAll(
 WaitHandle* waitHandles[]
);
[JScript]
public static function WaitAll(
   waitHandles : WaitHandle[]
) : Boolean;

Parameters

waitHandles
A WaitHandle array containing the objects for which the current instance will wait. This array cannot contain multiple references to the same object (duplicates).

Return Value

true when every element in waitHandles has received a signal; otherwise the method never returns.

Exceptions

Exception Type Condition
ArgumentNullException The waitHandles parameter is a null reference (Nothing in Visual Basic) or one or more of the objects in the waitHandles array are a null reference (Nothing).
DuplicateWaitObjectException The waitHandles array contains elements that are duplicates.
NotSupportedException The number of objects in waitHandles is greater than the system permits.

-or-

The current thread is marked with the STAThreadAttribute, and waitHandles contains more than one element.

ApplicationException waitHandles is an array with no elements.

Remarks

Returns when all the handles are signaled. On some implementations, if more than 64 handles are passed, a NotSupportedException is thrown. If the array contains duplicates, the call will fail.

Note   The WaitAll method is not supported on threads that are marked with STAThreadAttribute.

Calling this overload is equivalent to calling the WaitAll(WaitHandle[],Int32,Boolean) overload, specifying -1 or Timeout.Infinite for the second parameter and false for the third parameter.

Example

[Visual Basic, C#, C++] The following code example shows how to use the thread pool to asynchronously create and write to a group of files. Each write operation is queued as a work item and signals when it is finished. The main thread waits for all the items to signal and then exits.

[Visual Basic] 
Imports System
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading

' Request permission to create and write files to C:\TestTest.
<Assembly: FileIOPermissionAttribute(SecurityAction.RequestMinimum, _
     All := "C:\TestTest")>

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

[C#] 
using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;

// Request permission to create and write files to C:\TestTest.
[assembly: FileIOPermissionAttribute(SecurityAction.RequestMinimum, 
     All = @"C:\TestTest")]

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();
        }
    }
}

[C++] 
#using <mscorlib.dll>
using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;

// Request permission to create and write files to C:\TestTest.
[assembly: FileIOPermissionAttribute(SecurityAction::RequestMinimum, 
     All = "C:\\TestTest")];

// Maintain state to pass to WriteToFile.
__gc class State
{
public:
    String* fileName;
    Byte byteArray __gc [];
    ManualResetEvent* manualEvent;

    State(String* fileName, Byte byteArray __gc [], 
        ManualResetEvent* manualEvent) : fileName(fileName), 
        byteArray(byteArray), manualEvent(manualEvent) {}
};

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

public:
    static void WriteToFile(Object* state)
    {
        int workItemNumber = workItemCount;
        Interlocked::Increment(&workItemCount);
        Console::WriteLine(S"Starting work item {0}.", 
            workItemNumber.ToString());
        State* stateInfo = dynamic_cast<State*>(state);
        FileStream* fileWriter;

        // 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 != 0)
            {
                fileWriter->Close();
            }

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

void main()
{
    const int numberOfFiles = 5;
    String* dirName = "C:\\TestTest";
    String* fileName;

    Byte byteArray __gc [];
    Random* randomGenerator = new Random();

    ManualResetEvent* manualEvents __gc [] = 
        new ManualResetEvent* __gc [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 __gc [1000000];
        randomGenerator->NextBytes(byteArray);

        manualEvents[i] = new ManualResetEvent(false);

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

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

[JScript] No example is available for JScript. To view a Visual Basic, C#, or C++ example, click the Language Filter button Language Filter in the upper-left corner of the page.

Requirements

Platforms: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 family, Common Language Infrastructure (CLI) Standard

See Also

WaitHandle Class | WaitHandle Members | System.Threading Namespace | WaitHandle.WaitAll Overload List

Show: