WaitHandle.WaitAll Methode

Definition

Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen.

Überlädt

WaitAll(WaitHandle[], TimeSpan, Boolean)

Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein TimeSpan-Wert zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll.

WaitAll(WaitHandle[], Int32, Boolean)

Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein Int32-Wert zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll.

WaitAll(WaitHandle[], TimeSpan)

Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem TimeSpan-Wert an.

WaitAll(WaitHandle[], Int32)

Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem Int32-Wert an.

WaitAll(WaitHandle[])

Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen.

WaitAll(WaitHandle[], TimeSpan, Boolean)

Quelle:
WaitHandle.cs
Quelle:
WaitHandle.cs
Quelle:
WaitHandle.cs

Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein TimeSpan-Wert zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll.

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

Parameter

waitHandles
WaitHandle[]

Ein WaitHandle-Array mit den Objekten, auf die die aktuelle Instanz wartet. Dieses Array kann nicht mehrere Verweise auf dasselbe Objekt enthalten.

timeout
TimeSpan

Eine TimeSpan-Struktur, die die Anzahl der zu Millisekunden für die Wartezeit angibt, oder eine TimeSpan-Struktur, die -1 Millisekunden angibt, also eine unbeschränkte Wartezeit.

exitContext
Boolean

true, um die Synchronisierungsdomäne für den Kontext vor dem Wartevorgang (sofern in einem synchronisierten Kontext) zu verlassen und diese anschließend erneut abzurufen, andernfalls false.

Gibt zurück

true, wenn jedes Element in waitHandles ein Signal empfangen hat, andernfalls false.

Ausnahmen

Der waitHandles-Parameter ist null.

- oder -

Mindestens ein Objekt im waitHandles-Array ist null.

- oder -

waitHandles ist ein Array ohne Elemente, und die .NET Framework-Version ist 2.0 oder höher.

Das waitHandles-Array enthält doppelte Elemente.

Die Anzahl von Objekten in waitHandles ist größer, als das System erlaubt.

- oder -

Das STAThreadAttribute-Attribut wird für den aktuellen Thread auf die Threadprozedur angewendet, und waitHandles enthält mehrere Elemente.

waitHandles ist ein Array ohne Elemente, und die .NET Framework-Version ist 1.0 oder 1.1.

timeout ist eine negative Zahl ungleich -1 Millisekunden, die ein unendliches Timeout darstellt.

- oder -

timeout ist größer als Int32.MaxValue.

Der Wartevorgang wird beendet, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.

Das waitHandles-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.

Beispiele

Das folgende Codebeispiel zeigt, wie Sie den Threadpool verwenden, um eine Gruppe von Dateien asynchron zu erstellen und in diese zu schreiben. Jeder Schreibvorgang wird als Arbeitselement in die Warteschlange gestellt und signalisiert, wenn er abgeschlossen ist. Der Hauptthread wartet, bis alle Elemente signalisiert werden, und wird dann beendet.

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

Hinweise

Wenn timeout null ist, wird die -Methode nicht blockiert. Er testet den Zustand der Wartevorgänge und gibt sofort zurück.

Wenn ein Mutex verlassen wird, wird ein AbandonedMutexException ausgelöst. Ein aufgegebener Mutex weist häufig auf einen schwerwiegenden Codierungsfehler hin. Bei einem systemweiten Mutex kann dies darauf hindeuten, dass eine Anwendung abrupt beendet wurde (z. B. mithilfe des Windows Task-Managers). Die Ausnahme enthält Informationen, die für das Debuggen nützlich sind.

Die WaitAll -Methode gibt zurück, wenn die Wartezeit beendet wird. Dies bedeutet, dass entweder alle Handles signalisiert werden oder ein Timeout auftritt. Wenn mehr als 64 Handles übergeben werden, wird ein NotSupportedException ausgelöst. Wenn das Array Duplikate enthält, schlägt der Aufruf fehl.

Hinweis

Die WaitAll -Methode wird für Threads im STA Zustand nicht unterstützt.

Der Maximalwert für timeout ist Int32.MaxValue.

Beenden des Kontexts

Der exitContext -Parameter hat keine Auswirkung, es sei denn, diese Methode wird aus einem nicht standardmäßig verwalteten Kontext aufgerufen. Der verwaltete Kontext kann nicht standardmäßig sein, wenn sich Ihr Thread in einem Aufruf einer Instanz einer klasse befindet, die von ContextBoundObjectabgeleitet wird. Auch wenn Sie derzeit eine Methode für eine Klasse ausführen, die nicht von ContextBoundObjectabgeleitet ist, wie String, können Sie sich in einem nicht standardmäßigen Kontext befinden, wenn sich ein ContextBoundObject in Ihrem Stapel in der aktuellen Anwendungsdomäne befindet.

Wenn Ihr Code in einem nicht standardmäßigen Kontext ausgeführt wird, bewirkt die Angabe true von für exitContext , dass der Thread den nicht standardmäßig verwalteten Kontext beendet (d. h. zum Übergang in den Standardkontext), bevor diese Methode ausgeführt wird. Der Thread kehrt zum ursprünglichen nicht standardmäßigen Kontext zurück, nachdem der Aufruf dieser Methode abgeschlossen wurde.

Das Beenden des Kontexts kann nützlich sein, wenn die kontextgebundene Klasse über das SynchronizationAttribute -Attribut verfügt. In diesem Fall werden alle Aufrufe von Membern der -Klasse automatisch synchronisiert, und die Synchronisierungsdomäne ist der gesamte Codetext der Klasse. Wenn Code im Aufrufstapel eines Members diese Methode aufruft und für exitContextangibttrue, beendet der Thread die Synchronisierungsdomäne, sodass ein Thread, der bei einem Aufruf eines beliebigen Elements des -Objekts blockiert wird, fortfahren kann. Wenn diese Methode zurückgibt, muss der Thread, der den Aufruf ausgeführt hat, warten, um wieder in die Synchronisierungsdomäne zu wechseln.

Gilt für:

WaitAll(WaitHandle[], Int32, Boolean)

Quelle:
WaitHandle.cs
Quelle:
WaitHandle.cs
Quelle:
WaitHandle.cs

Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen, wobei ein Int32-Wert zum Angeben des Zeitintervalls verwendet wird, und gibt an, ob die Synchronisierungsdomäne vor dem Wartevorgang verlassen werden soll.

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

Parameter

waitHandles
WaitHandle[]

Ein WaitHandle-Array mit den Objekten, auf die die aktuelle Instanz wartet. Dieses Array kann nicht mehrere Verweise auf dasselbe Objekt (Duplikate) enthalten.

millisecondsTimeout
Int32

Die Anzahl von Millisekunden, die gewartet wird, oder Infinite (-1) für Warten ohne Timeout.

exitContext
Boolean

true, um die Synchronisierungsdomäne für den Kontext vor dem Wartevorgang (sofern in einem synchronisierten Kontext) zu verlassen und diese anschließend erneut abzurufen, andernfalls false.

Gibt zurück

true, wenn jedes Element in waitHandles ein Signal empfangen hat, andernfalls false.

Ausnahmen

Der waitHandles-Parameter ist null.

- oder -

Mindestens ein Objekt im waitHandles-Array ist null.

- oder -

waitHandles ist ein Array ohne Elemente, und die .NET Framework-Version ist 2.0 oder höher.

Das waitHandles-Array enthält doppelte Elemente.

Die Anzahl von Objekten in waitHandles ist größer, als das System erlaubt.

- oder -

Der aktuelle Thread ist im STA-Zustand, und waitHandles enthält mehrere Elemente.

waitHandles ist ein Array ohne Elemente, und die .NET Framework-Version ist 1.0 oder 1.1.

millisecondsTimeout ist eine negative Zahl, jedoch nicht -1, was einen unbeschränkten Timeout darstellt.

Der Wartevorgang wird abgeschlossen, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.

Das waitHandles-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.

Beispiele

Das folgende Codebeispiel zeigt, wie Sie den Threadpool verwenden, um eine Gruppe von Dateien asynchron zu erstellen und in diese zu schreiben. Jeder Schreibvorgang wird als Arbeitselement in die Warteschlange gestellt und signalisiert, wenn er abgeschlossen ist. Der Hauptthread wartet, bis alle Elemente signalisiert werden, und wird dann beendet.

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

Hinweise

Wenn millisecondsTimeout null ist, wird die -Methode nicht blockiert. Er testet den Zustand der Wartevorgänge und gibt sofort zurück.

Wenn ein Mutex verlassen wird, wird ein AbandonedMutexException ausgelöst. Ein aufgegebener Mutex weist häufig auf einen schwerwiegenden Codierungsfehler hin. Bei einem systemweiten Mutex kann dies darauf hindeuten, dass eine Anwendung abrupt beendet wurde (z. B. mithilfe des Windows Task-Managers). Die Ausnahme enthält Informationen, die für das Debuggen nützlich sind.

Die WaitAll Methode gibt zurück, wenn die Wartezeit beendet wird, d. h. entweder, wenn alle Handles signalisiert werden oder wenn ein Timeout auftritt. Wenn mehr als 64 Handles übergeben werden, wird ein NotSupportedException ausgelöst. Wenn im Array Duplikate vorhanden sind, schlägt der Aufruf mit einem fehl DuplicateWaitObjectException.

Hinweis

Die WaitAll -Methode wird für Threads im STA Zustand nicht unterstützt.

Beenden des Kontexts

Der exitContext -Parameter hat keine Auswirkung, es sei denn, diese Methode wird aus einem nicht standardmäßig verwalteten Kontext aufgerufen. Der verwaltete Kontext kann nicht standardmäßig sein, wenn sich Ihr Thread in einem Aufruf einer Instanz einer klasse befindet, die von ContextBoundObjectabgeleitet wird. Auch wenn Sie derzeit eine Methode für eine Klasse ausführen, die nicht von ContextBoundObjectabgeleitet ist, wie String, können Sie sich in einem nicht standardmäßigen Kontext befinden, wenn sich ein ContextBoundObject in Ihrem Stapel in der aktuellen Anwendungsdomäne befindet.

Wenn Ihr Code in einem nicht standardmäßigen Kontext ausgeführt wird, bewirkt die Angabe true von für exitContext , dass der Thread den nicht standardmäßig verwalteten Kontext beendet (d. h. zum Übergang in den Standardkontext), bevor diese Methode ausgeführt wird. Der Thread kehrt zum ursprünglichen nicht standardmäßigen Kontext zurück, nachdem der Aufruf dieser Methode abgeschlossen wurde.

Das Beenden des Kontexts kann nützlich sein, wenn die kontextgebundene Klasse über das SynchronizationAttribute -Attribut verfügt. In diesem Fall werden alle Aufrufe von Membern der -Klasse automatisch synchronisiert, und die Synchronisierungsdomäne ist der gesamte Codetext der Klasse. Wenn Code im Aufrufstapel eines Members diese Methode aufruft und für exitContextangibttrue, beendet der Thread die Synchronisierungsdomäne, sodass ein Thread, der bei einem Aufruf eines beliebigen Elements des -Objekts blockiert wird, fortfahren kann. Wenn diese Methode zurückgibt, muss der Thread, der den Aufruf ausgeführt hat, warten, um wieder in die Synchronisierungsdomäne zu wechseln.

Gilt für:

WaitAll(WaitHandle[], TimeSpan)

Quelle:
WaitHandle.cs
Quelle:
WaitHandle.cs
Quelle:
WaitHandle.cs

Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem TimeSpan-Wert an.

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

Parameter

waitHandles
WaitHandle[]

Ein WaitHandle-Array mit den Objekten, auf die die aktuelle Instanz wartet. Dieses Array kann nicht mehrere Verweise auf dasselbe Objekt enthalten.

timeout
TimeSpan

Eine TimeSpan-Struktur, die die Anzahl der zu Millisekunden für die Wartezeit angibt, oder eine TimeSpan-Struktur, die -1 Millisekunden angibt, also eine unbeschränkte Wartezeit.

Gibt zurück

true, wenn jedes Element in waitHandles ein Signal empfangen hat, andernfalls false.

Ausnahmen

Der waitHandles-Parameter ist null.

- oder -

Mindestens ein Objekt im waitHandles-Array ist null.

- oder -

waitHandles ist ein Array ohne Elemente.

Das waitHandles-Array enthält doppelte Elemente.

Hinweis: Fangen Sie in .NET für Windows Store-Apps oder der Portablen Klassenbibliothek stattdessen die Basisklassenausnahme ArgumentException ab.

Die Anzahl von Objekten in waitHandles ist größer, als das System erlaubt.

- oder -

Der aktuelle Thread ist im STA-Zustand, und waitHandles enthält mehrere Elemente.

timeout ist eine negative Zahl ungleich -1 Millisekunden, die ein unendliches Timeout darstellt.

- oder -

timeout ist größer als Int32.MaxValue.

Der Wartevorgang wird beendet, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.

Das waitHandles-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.

Hinweise

Wenn timeout null ist, wird die -Methode nicht blockiert. Er testet den Zustand der Wartevorgänge und gibt sofort zurück.

Die WaitAll -Methode gibt zurück, wenn die Wartezeit beendet wird. Dies bedeutet, dass entweder alle Handles signalisiert werden oder ein Timeout auftritt. Wenn mehr als 64 Handles übergeben werden, wird ein NotSupportedException ausgelöst. Wenn das Array Duplikate enthält, schlägt der Aufruf fehl.

Hinweis

Die WaitAll -Methode wird für Threads im STA Zustand nicht unterstützt.

Der Maximalwert für timeout ist Int32.MaxValue.

Das Aufrufen dieser Methodenüberladung ist identisch mit dem Aufrufen der WaitAll(WaitHandle[], TimeSpan, Boolean) Überladung und angeben false für exitContext.

Gilt für:

WaitAll(WaitHandle[], Int32)

Quelle:
WaitHandle.cs
Quelle:
WaitHandle.cs
Quelle:
WaitHandle.cs

Wartet auf den Empfang eines Signals für alle Elemente im angegebenen Array und gibt das Zeitintervall mit einem Int32-Wert an.

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

Parameter

waitHandles
WaitHandle[]

Ein WaitHandle-Array mit den Objekten, auf die die aktuelle Instanz wartet. Dieses Array kann nicht mehrere Verweise auf dasselbe Objekt (Duplikate) enthalten.

millisecondsTimeout
Int32

Die Anzahl von Millisekunden, die gewartet wird, oder Infinite (-1) für Warten ohne Timeout.

Gibt zurück

true, wenn jedes Element in waitHandles ein Signal empfangen hat, andernfalls false.

Ausnahmen

Der waitHandles-Parameter ist null.

- oder -

Mindestens ein Objekt im waitHandles-Array ist null.

- oder -

waitHandles ist ein Array ohne Elemente.

Das waitHandles-Array enthält doppelte Elemente.

Hinweis: Fangen Sie in .NET für Windows Store-Apps oder der Portablen Klassenbibliothek stattdessen die Basisklassenausnahme ArgumentException ab.

Die Anzahl von Objekten in waitHandles ist größer, als das System erlaubt.

- oder -

Der aktuelle Thread ist im STA-Zustand, und waitHandles enthält mehrere Elemente.

millisecondsTimeout ist eine negative Zahl, jedoch nicht -1, was einen unbeschränkten Timeout darstellt.

Der Wartevorgang wird abgeschlossen, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.

Das waitHandles-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.

Hinweise

Wenn millisecondsTimeout null ist, wird die -Methode nicht blockiert. Er testet den Zustand der Wartevorgänge und gibt sofort zurück.

Die WaitAll Methode gibt zurück, wenn die Wartezeit beendet wird, d. h. entweder, wenn alle Handles signalisiert werden oder wenn ein Timeout auftritt. Wenn mehr als 64 Handles übergeben werden, wird ein NotSupportedException ausgelöst. Wenn im Array Duplikate vorhanden sind, schlägt der Aufruf mit einem fehl DuplicateWaitObjectException.

Hinweis

Die WaitAll -Methode wird für Threads im STA Zustand nicht unterstützt.

Das Aufrufen dieser Methodenüberladung ist identisch mit dem Aufrufen der WaitAll(WaitHandle[], Int32, Boolean) Überladung und angeben false für exitContext.

Gilt für:

WaitAll(WaitHandle[])

Quelle:
WaitHandle.cs
Quelle:
WaitHandle.cs
Quelle:
WaitHandle.cs

Wartet, bis alle Elemente im angegebenen Array ein Signal empfangen.

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

Parameter

waitHandles
WaitHandle[]

Ein WaitHandle-Array mit den Objekten, auf die die aktuelle Instanz wartet. Dieses Array kann nicht mehrere Verweise auf dasselbe Objekt enthalten.

Gibt zurück

true, wenn jedes Element in waitHandles ein Signal empfangen hat, andernfalls wird die Methode nicht beendet.

Ausnahmen

Der waitHandles-Parameter ist null. - oder -

Mindestens ein Objekt im waitHandles-Array ist null.

- oder -

waitHandles ist ein Array ohne Elemente, und die .NET Framework-Version ist 2.0 oder höher.

Das waitHandles-Array enthält doppelte Elemente.

Hinweis: Fangen Sie in .NET für Windows Store-Apps oder der Portablen Klassenbibliothek stattdessen die Basisklassenausnahme ArgumentException ab.

Die Anzahl von Objekten in waitHandles ist größer, als das System erlaubt.

- oder -

Der aktuelle Thread ist im STA-Zustand, und waitHandles enthält mehrere Elemente.

waitHandles ist ein Array ohne Elemente, und die .NET Framework-Version ist 1.0 oder 1.1.

Der Wartevorgang wird beendet, weil ein Thread beendet wurde, ohne ein Mutex freizugeben.

Das waitHandles-Array enthält einen transparenten Proxy für ein WaitHandle in einer anderen Anwendungsdomäne.

Beispiele

Das folgende Codebeispiel zeigt, wie Sie den Threadpool verwenden, um eine Gruppe von Dateien asynchron zu erstellen und in diese zu schreiben. Jeder Schreibvorgang wird als Arbeitselement in die Warteschlange gestellt und signalisiert, wenn er abgeschlossen ist. Der Hauptthread wartet, bis alle Elemente signalisiert werden, und wird dann beendet.

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

Hinweise

AbandonedMutexException ist neu in .NET Framework, Version 2.0. In früheren Versionen gibt die WaitAll Methode zurück true , wenn ein Mutex abgebrochen wird. Ein aufgegebener Mutex weist häufig auf einen schwerwiegenden Codierungsfehler hin. Bei einem systemweiten Mutex kann dies darauf hindeuten, dass eine Anwendung abrupt beendet wurde (z. B. mithilfe des Windows Task-Managers). Die Ausnahme enthält Informationen, die für das Debuggen nützlich sind.

Die WaitAll -Methode gibt zurück, wenn alle Handles signalisiert werden. Wenn mehr als 64 Handles übergeben werden, wird ein NotSupportedException ausgelöst. Wenn das Array Duplikate enthält, schlägt der Aufruf mit einem fehl DuplicateWaitObjectException.

Hinweis

Die WaitAll -Methode wird für Threads im STA Zustand nicht unterstützt.

Das Aufrufen dieser Methodenüberladung entspricht dem Aufrufen der WaitAll(WaitHandle[], Int32, Boolean) Methodenüberladung und dem Angeben von -1 (oder Timeout.Infinite) für millisecondsTimeout und true .exitContext

Gilt für: