Sdílet prostřednictvím


WaitHandle.WaitAll Metoda

Definice

Čeká na přijetí signálu všemi prvky v zadaném poli.

Přetížení

WaitAll(WaitHandle[], TimeSpan, Boolean)

Čeká, až všechny prvky v zadaném poli obdrží signál, pomocí TimeSpan hodnoty pro zadání časového intervalu a určení, zda má být doména synchronizace ukončena před čekáním.

WaitAll(WaitHandle[], Int32, Boolean)

Počká, až všechny prvky v zadaném poli obdrží signál, pomocí Int32 hodnoty určí časový interval a určí, zda má být doména synchronizace ukončena před čekáním.

WaitAll(WaitHandle[], TimeSpan)

Čeká na přijetí signálu všemi prvky v zadaném poli pomocí TimeSpan hodnoty pro určení časového intervalu.

WaitAll(WaitHandle[], Int32)

Čeká na přijetí signálu všemi prvky v zadaném poli pomocí Int32 hodnoty pro určení časového intervalu.

WaitAll(WaitHandle[])

Čeká na přijetí signálu všemi prvky v zadaném poli.

WaitAll(WaitHandle[], TimeSpan, Boolean)

Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs

Čeká, až všechny prvky v zadaném poli obdrží signál, pomocí TimeSpan hodnoty pro zadání časového intervalu a určení, zda má být doména synchronizace ukončena před čekáním.

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

Parametry

waitHandles
WaitHandle[]

Pole WaitHandle obsahující objekty, na které bude aktuální instance čekat. Toto pole nemůže obsahovat více odkazů na stejný objekt.

timeout
TimeSpan

A TimeSpan , který představuje počet milisekund čekat, nebo , TimeSpan který představuje -1 milisekund, čekat po neomezenou dobu.

exitContext
Boolean

trueopustit synchronizační doménu pro kontext před čekáním (pokud je v synchronizovaném kontextu) a následně ji znovu získat; v opačném případě . false

Návraty

true pokud každý prvek v waitHandles souboru obdržel signál, jinak false.

Výjimky

Parametr waitHandles je null.

-nebo-

Jeden nebo více objektů v waitHandles poli je null.

-nebo-

waitHandles je pole bez prvků a verze rozhraní .NET Framework je 2.0 nebo novější.

Pole waitHandles obsahuje prvky, které jsou duplicitní.

Počet objektů v souboru waitHandles je větší, než systém povoluje.

-nebo-

Atribut STAThreadAttribute je použit pro proceduru vlákna pro aktuální vlákno a waitHandles obsahuje více než jeden prvek.

waitHandles je pole bez prvků a verze rozhraní .NET Framework je 1.0 nebo 1.1.

timeout je záporné číslo jiné než -1 milisekund, které představuje nekonečný časový limit.

-nebo-

timeout je větší než Int32.MaxValue.

Čekání bylo ukončeno, protože vlákno bylo ukončeno bez uvolnění mutex.

Pole waitHandles obsahuje transparentní proxy server pro WaitHandle objekt v jiné doméně aplikace.

Příklady

Následující příklad kódu ukazuje, jak použít fond vláken k asynchronnímu vytváření a zápisu do skupiny souborů. Každá operace zápisu je zařazena do fronty jako pracovní položka a signalizuje, že je dokončena. Hlavní vlákno čeká na signál všech položek a poté se ukončí.

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

Poznámky

Pokud timeout je nula, metoda neblokuje. Otestuje stav obslužných rutin čekání a okamžitě se vrátí.

Pokud dojde k opuštění mutexu, AbandonedMutexException vyvolá se chyba . Opuštěný mutex často značí závažnou chybu kódování. V případě systémového mutexu to může znamenat, že aplikace byla náhle ukončena (například pomocí Správce úloh systému Windows). Výjimka obsahuje informace užitečné pro ladění.

Metoda WaitAll vrátí při ukončení čekání, což znamená, že jsou signalizovaly všechny popisovače nebo dojde k vypršení časového limitu. Pokud je předáno více než 64 popisovačů, NotSupportedException je vyvolán . Pokud pole obsahuje duplicity, volání se nezdaří.

Poznámka

Metoda WaitAll není podporována u vláken ve STA stavu .

Maximální hodnota pro timeout je Int32.MaxValue.

Ukončení kontextu

Parametr exitContext nemá žádný vliv, pokud tato metoda není volána z nevýkonných spravovaných kontextů. Spravovaný kontext může být nevýchozí, pokud se vlákno nachází uvnitř volání instance třídy odvozené z ContextBoundObject. I když aktuálně spouštíte metodu pro třídu, která není odvozená z ContextBoundObject, jako Stringje , můžete být v nevýchozím kontextu, pokud je ve vašem zásobníku ContextBoundObject v aktuální doméně aplikace.

Když se váš kód spouští v nevýchozím kontextu, určení true for exitContext způsobí, že vlákno ukončí nevýchozí spravovaný kontext (tj. pro přechod do výchozího kontextu) před spuštěním této metody. Vlákno se po dokončení volání této metody vrátí k původnímu nevýchozí kontext.

Ukončení kontextu může být užitečné, pokud kontextová třída má SynchronizationAttribute atribut . V takovém případě jsou všechna volání členů třídy automaticky synchronizována a doména synchronizace je celé tělo kódu pro třídu. Pokud kód v zásobníku volání člena volá tuto metodu a určuje true pro exitContext, vlákno opustí synchronizační doménu, což umožňuje vlákno blokované při volání libovolného člena objektu pokračovat. Když tato metoda vrátí, vlákno, které provedlo volání, musí počkat na opětovné zadání synchronizační domény.

Platí pro

WaitAll(WaitHandle[], Int32, Boolean)

Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs

Čeká, až všechny prvky v zadaném poli obdrží signál, pomocí Int32 hodnoty pro určení časového intervalu a určení, zda se má před čekáním ukončit synchronizační doména.

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

Parametry

waitHandles
WaitHandle[]

Pole WaitHandle obsahující objekty, na které bude aktuální instance čekat. Toto pole nemůže obsahovat více odkazů na stejný objekt (duplicity).

millisecondsTimeout
Int32

Počet milisekund, které se mají čekat, nebo Infinite (-1) čekání na neomezenou dobu.

exitContext
Boolean

trueopustit synchronizační doménu pro kontext před čekáním (pokud je v synchronizovaném kontextu) a následně ji znovu získat; v opačném případě . false

Návraty

truepokud každý prvek v waitHandles systému obdržel signál, jinak . false

Výjimky

Parametr waitHandles je null.

-nebo-

Jeden nebo více objektů v waitHandles poli je null.

-nebo-

waitHandles je pole bez prvků a verze rozhraní .NET Framework je 2.0 nebo novější.

Pole waitHandles obsahuje prvky, které jsou duplicitní.

Počet objektů v souboru waitHandles je větší, než systém povoluje.

-nebo-

Aktuální vlákno je ve STA stavu a waitHandles obsahuje více než jeden prvek.

waitHandles je pole bez prvků a verze rozhraní .NET Framework je 1.0 nebo 1.1.

millisecondsTimeout je záporné číslo jiné než -1, které představuje nekonečný časový limit.

Čekání bylo dokončeno, protože vlákno bylo ukončeno bez uvolnění mutex.

Pole waitHandles obsahuje transparentní proxy server pro WaitHandle objekt v jiné doméně aplikace.

Příklady

Následující příklad kódu ukazuje, jak použít fond vláken k asynchronnímu vytváření a zápisu do skupiny souborů. Každá operace zápisu je zařazena do fronty jako pracovní položka a signalizuje, že je dokončena. Hlavní vlákno čeká na signál všech položek a poté se ukončí.

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

Poznámky

Pokud millisecondsTimeout je nula, metoda neblokuje. Otestuje stav obslužných rutin čekání a okamžitě se vrátí.

Pokud dojde k opuštění mutexu, AbandonedMutexException vyvolá se chyba . Opuštěný mutex často značí závažnou chybu kódování. V případě systémového mutexu to může znamenat, že aplikace byla náhle ukončena (například pomocí Správce úloh systému Windows). Výjimka obsahuje informace užitečné pro ladění.

Metoda WaitAll vrátí při ukončení čekání, což znamená, že buď když jsou signalizovaly všechny popisovače, nebo když dojde k vypršení časového limitu. Pokud je předáno více než 64 popisovačů, NotSupportedException je vyvolán . Pokud jsou v poli duplicity, volání selže s DuplicateWaitObjectException.

Poznámka

Metoda WaitAll není podporována u vláken ve STA stavu .

Ukončení kontextu

Parametr exitContext nemá žádný vliv, pokud tato metoda není volána z nevýkonných spravovaných kontextů. Spravovaný kontext může být nevýchozí, pokud se vlákno nachází uvnitř volání instance třídy odvozené z ContextBoundObject. I když aktuálně spouštíte metodu pro třídu, která není odvozená z ContextBoundObject, jako Stringje , můžete být v nevýchozím kontextu, pokud je ve vašem zásobníku ContextBoundObject v aktuální doméně aplikace.

Když se váš kód spouští v nevýchozím kontextu, určení true for exitContext způsobí, že vlákno ukončí nevýchozí spravovaný kontext (tj. pro přechod do výchozího kontextu) před spuštěním této metody. Vlákno se po dokončení volání této metody vrátí k původnímu nevýchozí kontext.

Ukončení kontextu může být užitečné, pokud kontextová třída má SynchronizationAttribute atribut . V takovém případě jsou všechna volání členů třídy automaticky synchronizována a doména synchronizace je celé tělo kódu pro třídu. Pokud kód v zásobníku volání člena volá tuto metodu a určuje true pro exitContext, vlákno opustí synchronizační doménu, což umožňuje vlákno blokované při volání libovolného člena objektu pokračovat. Když tato metoda vrátí, vlákno, které provedlo volání, musí počkat na opětovné zadání synchronizační domény.

Platí pro

WaitAll(WaitHandle[], TimeSpan)

Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs

Čeká na přijetí signálu všemi prvky v zadaném poli pomocí TimeSpan hodnoty pro určení časového intervalu.

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

Parametry

waitHandles
WaitHandle[]

Pole WaitHandle obsahující objekty, na které bude aktuální instance čekat. Toto pole nemůže obsahovat více odkazů na stejný objekt.

timeout
TimeSpan

Hodnota TimeSpan , která představuje počet milisekund, které se mají čekat, nebo TimeSpan hodnota představující -1 milisekund, která má čekat neomezeně dlouho.

Návraty

truepokud každý prvek v waitHandles systému obdržel signál, jinak . false

Výjimky

Parametr waitHandles je null.

-nebo-

Jeden nebo více objektů v waitHandles poli je null.

-nebo-

waitHandles je pole bez prvků.

Pole waitHandles obsahuje prvky, které jsou duplicitní.

Poznámka: V aplikacích .NET pro Windows Store nebo v přenosné knihovně tříd místo toho zachyťte výjimku ArgumentExceptionzákladní třídy.

Počet objektů v systému waitHandles je větší, než systém povoluje.

-nebo-

Aktuální vlákno je ve STA stavu a waitHandles obsahuje více než jeden prvek.

timeout je záporné číslo jiné než -1 milisekund, což představuje nekonečný časový limit.

-nebo-

timeout je větší než Int32.MaxValue.

Čekání se ukončilo, protože vlákno skončilo bez uvolnění mutexu.

Pole waitHandles obsahuje transparentní proxy server v WaitHandle jiné doméně aplikace.

Poznámky

Pokud timeout je nula, metoda neblokuje. Testuje stav popisovačů čekání a okamžitě se vrátí.

Metoda WaitAll vrátí, když se čekání ukončí, což znamená, že buď jsou signaldovány všechny popisovače, nebo dojde k vypršení časového limitu. Pokud je předáno více než 64 popisovačů, NotSupportedException je vyvolán. Pokud pole obsahuje duplicity, volání selže.

Poznámka

Metoda WaitAll není podporována ve vláknech ve STA stavu.

Maximální hodnota pro timeout je Int32.MaxValue.

Volání přetížení této metody je stejné jako volání WaitAll(WaitHandle[], TimeSpan, Boolean) přetížení a zadání false pro exitContext.

Platí pro

WaitAll(WaitHandle[], Int32)

Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs

Čeká na přijetí signálu všemi prvky v zadaném poli pomocí Int32 hodnoty pro určení časového intervalu.

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

Parametry

waitHandles
WaitHandle[]

Pole WaitHandle obsahující objekty, na které bude aktuální instance čekat. Toto pole nemůže obsahovat více odkazů na stejný objekt (duplikáty).

millisecondsTimeout
Int32

Počet milisekund, které se mají čekat, nebo Infinite (-1) čekat na neomezenou dobu.

Návraty

truepokud každý prvek v waitHandles systému obdržel signál, jinak . false

Výjimky

Parametr waitHandles je null.

-nebo-

Jeden nebo více objektů v waitHandles poli je null.

-nebo-

waitHandles je pole bez prvků.

Pole waitHandles obsahuje prvky, které jsou duplicitní.

Poznámka: V aplikacích .NET pro Windows Store nebo v přenosné knihovně tříd místo toho zachyťte výjimku ArgumentExceptionzákladní třídy.

Počet objektů v systému waitHandles je větší, než systém povoluje.

-nebo-

Aktuální vlákno je ve STA stavu a waitHandles obsahuje více než jeden prvek.

millisecondsTimeout je záporné číslo jiné než -1, které představuje nekonečný časový limit.

Čekání se dokončilo, protože vlákno skončilo bez uvolnění mutexu.

Pole waitHandles obsahuje transparentní proxy server v WaitHandle jiné doméně aplikace.

Poznámky

Pokud millisecondsTimeout je nula, metoda neblokuje. Testuje stav popisovačů čekání a okamžitě se vrátí.

Metoda WaitAll vrátí při ukončení čekání, což znamená, že buď při signálu všech popisovačů, nebo když dojde k vypršení časového limitu. Pokud je předáno více než 64 popisovačů, NotSupportedException je vyvolán. Pokud jsou v poli duplicity, volání selže s chybou DuplicateWaitObjectException.

Poznámka

Metoda WaitAll není podporována ve vláknech ve STA stavu.

Volání přetížení této metody je stejné jako volání WaitAll(WaitHandle[], Int32, Boolean) přetížení a zadání false pro exitContext.

Platí pro

WaitAll(WaitHandle[])

Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs
Zdroj:
WaitHandle.cs

Čeká na přijetí signálu všemi prvky v zadaném poli.

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

Parametry

waitHandles
WaitHandle[]

Pole WaitHandle obsahující objekty, na které bude aktuální instance čekat. Toto pole nemůže obsahovat více odkazů na stejný objekt.

Návraty

true pokud každý prvek v waitHandles souboru obdržel signál, jinak metoda nikdy nevrátí.

Výjimky

Parametr waitHandles je null. -nebo-

Jeden nebo více objektů v waitHandles poli jsou null.

-nebo-

waitHandles je pole bez prvků a verze rozhraní .NET Framework je 2.0 nebo novější.

Pole waitHandles obsahuje prvky, které jsou duplicitní.

Poznámka: V aplikacích .NET pro Windows Store nebo v přenosné knihovně tříd místo toho zachyťte výjimku ArgumentExceptionzákladní třídy.

Počet objektů v systému waitHandles je větší, než systém povoluje.

-nebo-

Aktuální vlákno je ve STA stavu a waitHandles obsahuje více než jeden prvek.

waitHandles je pole bez prvků a verze rozhraní .NET Framework je 1.0 nebo 1.1.

Čekání se ukončilo, protože vlákno skončilo bez uvolnění mutexu.

Pole waitHandles obsahuje transparentní proxy server v WaitHandle jiné doméně aplikace.

Příklady

Následující příklad kódu ukazuje, jak použít fond vláken k asynchronnímu vytvoření a zápisu do skupiny souborů. Každá operace zápisu je zařazena do fronty jako pracovní položka a signalizuje, že je hotová. Hlavní vlákno počká na signál všech položek a pak se ukončí.

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

Poznámky

AbandonedMutexException je nový v rozhraní .NET Framework verze 2.0. V předchozích verzích WaitAll vrátí metoda při true opuštění mutexu. Opuštěný mutex často značí závažnou chybu kódování. V případě systémového mutexu to může znamenat, že aplikace byla náhle ukončena (například pomocí Správce úloh systému Windows). Výjimka obsahuje informace užitečné pro ladění.

Metoda WaitAll vrátí, když jsou signalizovaly všechny popisovače. Pokud je předáno více než 64 popisovačů, NotSupportedException je vyvolán. Pokud pole obsahuje duplicity, volání selže s chybou DuplicateWaitObjectException.

Poznámka

Metoda WaitAll není podporována ve vláknech ve STA stavu.

Volání přetížení této metody je ekvivalentní volání WaitAll(WaitHandle[], Int32, Boolean) přetížení metody a zadání -1 (nebo Timeout.Infinite) pro millisecondsTimeout a true pro exitContext.

Platí pro