WaitHandle.WaitAll Metodo

Definizione

Attende che tutti gli elementi nella matrice specificata ricevano un segnale.

Overload

WaitAll(WaitHandle[], TimeSpan, Boolean)

Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

WaitAll(WaitHandle[], Int32, Boolean)

Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore Int32 per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

WaitAll(WaitHandle[], TimeSpan)

Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo.

WaitAll(WaitHandle[], Int32)

Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore Int32 per specificare l'intervallo di tempo.

WaitAll(WaitHandle[])

Attende che tutti gli elementi nella matrice specificata ricevano un segnale.

WaitAll(WaitHandle[], TimeSpan, Boolean)

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

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

Parametri

waitHandles
WaitHandle[]

Matrice WaitHandle contenente gli oggetti per i quali l'istanza corrente attenderà. Questa matrice non può contenere più riferimenti allo stesso oggetto.

timeout
TimeSpan

Oggetto TimeSpan che rappresenta il numero di millisecondi di attesa oppure TimeSpan che rappresenta -1 millisecondi per un'attesa indefinita.

exitContext
Boolean

true per uscire dal dominio di sincronizzazione per il contesto prima dell'attesa, se all'interno di un contesto sincronizzato, e riacquisirlo successivamente; in caso contrario, false.

Restituisce

true quando ogni elemento in waitHandles ha ricevuto un segnale; in caso contrario false.

Eccezioni

Il valore del parametro waitHandles è null.

-oppure-

Uno o più oggetti nella matrice waitHandles sono null.

-oppure-

waitHandles è una matrice senza elementi e la versione di .NET Framework è 2.0 o successiva.

La matrice waitHandles contiene elementi duplicati.

Il numero di oggetti in waitHandles è maggiore di quello consentito dal sistema.

-oppure-

L'attributo STAThreadAttribute viene applicato alla routine del thread corrente e waitHandles contiene più di un elemento.

waitHandles è una matrice senza elementi e la versione di .NET Framework è 1.0 o 1.1.

timeout è un numero negativo diverso da -1 millisecondi, che rappresenta un timeout infinito.

-oppure-

timeout è maggiore di Int32.MaxValue.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

La matrice waitHandles contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.

Esempio

Nell'esempio di codice seguente viene illustrato come usare il pool di thread per creare e scrivere in modo asincrono in un gruppo di file. Ogni operazione di scrittura viene accodata come elemento di lavoro e segnala quando viene completata. Il thread principale attende che tutti gli elementi segnalino e quindi esce.

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

Commenti

Se timeout è zero, il metodo non viene bloccato. Verifica lo stato degli handle di attesa e restituisce immediatamente.

Se un mutex viene abbandonato, viene generata un'eccezione AbandonedMutexException . Un mutex abbandonato spesso indica un errore di codifica grave. Nel caso di un mutex a livello di sistema, potrebbe indicare che un'applicazione è stata terminata bruscamente ,ad esempio tramite Gestione attività di Windows. L'eccezione contiene informazioni utili per il debug.

Il WaitAll metodo restituisce quando termina l'attesa, ovvero vengono segnalate tutte le handle o si verifica un timeout. Se vengono passati più di 64 handle, viene generata un'eccezione NotSupportedException . Se la matrice contiene duplicati, la chiamata avrà esito negativo.

Nota

Il WaitAll metodo non è supportato nei thread nello STA stato.

Il valore massimo per timeout è Int32.MaxValue.

Uscita dal contesto

Il exitContext parametro non ha alcun effetto a meno che questo metodo non venga chiamato dall'interno di un contesto gestito non predefinito. Il contesto gestito può essere non predefinito se il thread si trova all'interno di una chiamata a un'istanza di una classe derivata da ContextBoundObject. Anche se attualmente si esegue un metodo in una classe che non è derivata da ContextBoundObject, ad esempio String, è possibile trovarsi in un contesto non predefinito se un ContextBoundObject oggetto si trova nello stack nel dominio applicazione corrente.

Quando il codice viene eseguito in un contesto non predefinito, se true si specifica per exitContext fa in modo che il thread esce dal contesto gestito non predefinito, ovvero per passare al contesto predefinito, prima di eseguire questo metodo. Il thread torna al contesto non predefinito originale al termine della chiamata a questo metodo.

L'uscita dal contesto può essere utile quando la classe associata al contesto ha l'attributo SynchronizationAttribute . In tal caso, tutte le chiamate ai membri della classe vengono sincronizzate automaticamente e il dominio di sincronizzazione è l'intero corpo del codice per la classe . Se il codice nello stack di chiamate di un membro chiama questo metodo e specifica true per exitContext, il thread esce dal dominio di sincronizzazione, che consente a un thread bloccato in una chiamata a qualsiasi membro dell'oggetto di continuare. Quando termina, il thread che ha eseguito la chiamata deve attendere di immettere nuovamente il dominio di sincronizzazione.

Si applica a

WaitAll(WaitHandle[], Int32, Boolean)

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore Int32 per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

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

Parametri

waitHandles
WaitHandle[]

Matrice WaitHandle contenente gli oggetti per i quali l'istanza corrente attenderà. Questa matrice non può contenere più riferimenti allo stesso oggetto (duplicati).

millisecondsTimeout
Int32

Numero di millisecondi di attesa oppure Infinite (-1) per un'attesa indefinita.

exitContext
Boolean

true per uscire dal dominio di sincronizzazione per il contesto prima dell'attesa, se all'interno di un contesto sincronizzato, e riacquisirlo successivamente; in caso contrario, false.

Restituisce

true se ogni elemento in waitHandles ha ricevuto un segnale; in caso contrario, false.

Eccezioni

Il valore del parametro waitHandles è null.

-oppure-

Uno o più oggetti nella matrice waitHandles sono null.

-oppure-

waitHandles è una matrice senza elementi e la versione di .NET Framework è 2.0 o successiva.

La matrice waitHandles contiene elementi duplicati.

Il numero di oggetti in waitHandles è maggiore di quello consentito dal sistema.

-oppure-

Il thread corrente è nello stato STA e waitHandles contiene più di un elemento.

waitHandles è una matrice senza elementi e la versione di .NET Framework è 1.0 o 1.1.

millisecondsTimeout è un numero negativo diverso da -1, che rappresenta un timeout infinito.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

La matrice waitHandles contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.

Esempio

Nell'esempio di codice seguente viene illustrato come usare il pool di thread per creare e scrivere in modo asincrono in un gruppo di file. Ogni operazione di scrittura viene accodata come elemento di lavoro e segnala quando viene completata. Il thread principale attende che tutti gli elementi segnalino e quindi esce.

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

Commenti

Se millisecondsTimeout è zero, il metodo non viene bloccato. Verifica lo stato degli handle di attesa e restituisce immediatamente.

Se un mutex viene abbandonato, viene generata un'eccezione AbandonedMutexException . Un mutex abbandonato spesso indica un errore di codifica grave. Nel caso di un mutex a livello di sistema, potrebbe indicare che un'applicazione è stata terminata bruscamente ,ad esempio tramite Gestione attività di Windows. L'eccezione contiene informazioni utili per il debug.

Il WaitAll metodo restituisce quando termina l'attesa, ovvero quando vengono segnalate tutte le handle o quando si verifica il timeout. Se vengono passati più di 64 handle, viene generata un'eccezione NotSupportedException . Se nella matrice sono presenti duplicati, la chiamata ha esito negativo con .DuplicateWaitObjectException

Nota

Il WaitAll metodo non è supportato nei thread nello STA stato.

Uscita dal contesto

Il exitContext parametro non ha alcun effetto a meno che questo metodo non venga chiamato dall'interno di un contesto gestito non predefinito. Il contesto gestito può essere non predefinito se il thread si trova all'interno di una chiamata a un'istanza di una classe derivata da ContextBoundObject. Anche se attualmente si esegue un metodo in una classe che non è derivata da ContextBoundObject, ad esempio String, è possibile trovarsi in un contesto non predefinito se un ContextBoundObject oggetto si trova nello stack nel dominio applicazione corrente.

Quando il codice viene eseguito in un contesto non predefinito, se true si specifica per exitContext fa in modo che il thread esce dal contesto gestito non predefinito, ovvero per passare al contesto predefinito, prima di eseguire questo metodo. Il thread torna al contesto non predefinito originale al termine della chiamata a questo metodo.

L'uscita dal contesto può essere utile quando la classe associata al contesto ha l'attributo SynchronizationAttribute . In tal caso, tutte le chiamate ai membri della classe vengono sincronizzate automaticamente e il dominio di sincronizzazione è l'intero corpo del codice per la classe . Se il codice nello stack di chiamate di un membro chiama questo metodo e specifica true per exitContext, il thread esce dal dominio di sincronizzazione, che consente a un thread bloccato in una chiamata a qualsiasi membro dell'oggetto di continuare. Quando questo metodo restituisce, il thread che ha effettuato la chiamata deve attendere di tornare al dominio di sincronizzazione.

Si applica a

WaitAll(WaitHandle[], TimeSpan)

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo.

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

Parametri

waitHandles
WaitHandle[]

Matrice WaitHandle contenente gli oggetti per i quali l'istanza corrente attenderà. Questa matrice non può contenere più riferimenti allo stesso oggetto.

timeout
TimeSpan

Oggetto TimeSpan che rappresenta il numero di millisecondi di attesa oppure TimeSpan che rappresenta -1 millisecondi per un'attesa indefinita.

Restituisce

true se ogni elemento in waitHandles ha ricevuto un segnale; in caso contrario, false.

Eccezioni

Il valore del parametro waitHandles è null.

-oppure-

Uno o più oggetti nella matrice waitHandles sono null.

-oppure-

waitHandles è una matrice senza elementi.

La matrice waitHandles contiene elementi duplicati.

Nota: nelle app .NET per Windows Store o nella libreria di classi portabile intercettare in alternativa l'eccezione della classe di base ArgumentException.

Il numero di oggetti in waitHandles è maggiore di quello consentito dal sistema.

-oppure-

Il thread corrente è nello stato STA e waitHandles contiene più di un elemento.

timeout è un numero negativo diverso da -1 millisecondi, che rappresenta un timeout infinito.

-oppure-

timeout è maggiore di Int32.MaxValue.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

La matrice waitHandles contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.

Commenti

Se timeout è zero, il metodo non blocca. Verifica lo stato degli handle di attesa e restituisce immediatamente.

Il WaitAll metodo restituisce quando termina l'attesa, ovvero tutti gli handle vengono segnalati o si verifica un timeout. Se vengono passati più di 64 handle, viene generato un NotSupportedException oggetto. Se la matrice contiene duplicati, la chiamata avrà esito negativo.

Nota

Il WaitAll metodo non è supportato nei thread nello STA stato.

Il valore massimo per timeout è Int32.MaxValue.

La chiamata all'overload di questo metodo è uguale a quella di chiamare l'overload WaitAll(WaitHandle[], TimeSpan, Boolean) e specificare false per exitContext.

Si applica a

WaitAll(WaitHandle[], Int32)

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Attende che tutti gli elementi nella matrice specificata ricevano un segnale, usando un valore Int32 per specificare l'intervallo di tempo.

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

Parametri

waitHandles
WaitHandle[]

Matrice WaitHandle contenente gli oggetti per i quali l'istanza corrente attenderà. Questa matrice non può contenere più riferimenti allo stesso oggetto (duplicati).

millisecondsTimeout
Int32

Numero di millisecondi di attesa oppure Infinite (-1) per un'attesa indefinita.

Restituisce

true se ogni elemento in waitHandles ha ricevuto un segnale; in caso contrario, false.

Eccezioni

Il valore del parametro waitHandles è null.

-oppure-

Uno o più oggetti nella matrice waitHandles sono null.

-oppure-

waitHandles è una matrice senza elementi.

La matrice waitHandles contiene elementi duplicati.

Nota: nelle app .NET per Windows Store o nella libreria di classi portabile intercettare in alternativa l'eccezione della classe di base ArgumentException.

Il numero di oggetti in waitHandles è maggiore di quello consentito dal sistema.

-oppure-

Il thread corrente è nello stato STA e waitHandles contiene più di un elemento.

millisecondsTimeout è un numero negativo diverso da -1, che rappresenta un timeout infinito.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

La matrice waitHandles contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.

Commenti

Se millisecondsTimeout è zero, il metodo non blocca. Verifica lo stato degli handle di attesa e restituisce immediatamente.

Il WaitAll metodo restituisce quando termina l'attesa, ovvero quando vengono segnalati tutti gli handle o quando si verifica il timeout. Se vengono passati più di 64 handle, viene generato un NotSupportedException oggetto. Se nella matrice sono presenti duplicati, la chiamata ha esito negativo con un DuplicateWaitObjectExceptionoggetto .

Nota

Il WaitAll metodo non è supportato nei thread nello STA stato.

La chiamata all'overload di questo metodo è uguale a quella di chiamare l'overload WaitAll(WaitHandle[], Int32, Boolean) e specificare false per exitContext.

Si applica a

WaitAll(WaitHandle[])

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Attende che tutti gli elementi nella matrice specificata ricevano un segnale.

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

Parametri

waitHandles
WaitHandle[]

Matrice WaitHandle contenente gli oggetti per i quali l'istanza corrente attenderà. Questa matrice non può contenere più riferimenti allo stesso oggetto.

Restituisce

true se ogni elemento in waitHandles ha ricevuto un segnale; in caso contrario, il metodo non restituisce alcun risultato.

Eccezioni

Il valore del parametro waitHandles è null. -oppure-

Uno o più oggetti nella matrice waitHandles sono null.

-oppure-

waitHandles è una matrice senza elementi e la versione di .NET Framework è 2.0 o successiva.

La matrice waitHandles contiene elementi duplicati.

Nota: nelle app .NET per Windows Store o nella libreria di classi portabile intercettare in alternativa l'eccezione della classe di base ArgumentException.

Il numero di oggetti in waitHandles è maggiore di quello consentito dal sistema.

-oppure-

Il thread corrente è nello stato STA e waitHandles contiene più di un elemento.

waitHandles è una matrice senza elementi e la versione di .NET Framework è 1.0 o 1.1.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

La matrice waitHandles contiene un proxy trasparente per un oggetto WaitHandle in un altro dominio di applicazione.

Esempio

Nell'esempio di codice seguente viene illustrato come usare il pool di thread per creare e scrivere in modo asincrono in un gruppo di file. Ogni operazione di scrittura viene accodata come elemento di lavoro e segnala al termine. Il thread principale attende che tutti gli elementi segnalino e quindi esci.

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

Commenti

AbandonedMutexException è nuovo in .NET Framework versione 2.0. Nelle versioni precedenti, il WaitAll metodo restituisce true quando viene abbandonato un mutex. Un mutex abbandonato spesso indica un grave errore di codifica. Nel caso di un mutex a livello di sistema, potrebbe indicare che un'applicazione è stata terminata bruscamente (ad esempio usando Gestione attività di Windows). L'eccezione contiene informazioni utili per il debug.

Il WaitAll metodo restituisce quando vengono segnalati tutti gli handle. Se vengono passati più di 64 handle, viene generato un NotSupportedException oggetto. Se la matrice contiene duplicati, la chiamata ha esito negativo con un DuplicateWaitObjectExceptionoggetto .

Nota

Il WaitAll metodo non è supportato nei thread nello STA stato.

La chiamata all'overload di questo metodo equivale a chiamare l'overload del WaitAll(WaitHandle[], Int32, Boolean) metodo e specificare -1 (o Timeout.Infinite) per millisecondsTimeout e true per exitContext.

Si applica a