WaitHandle.WaitAll Metoda

Definicja

Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy.

Przeciążenia

WaitAll(WaitHandle[], TimeSpan, Boolean)

Czeka na odbieranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu TimeSpan wartości w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

WaitAll(WaitHandle[], Int32, Boolean)

Czeka, aż wszystkie elementy w określonej tablicy otrzymają sygnał, używając Int32 wartości w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

WaitAll(WaitHandle[], TimeSpan)

Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu TimeSpan wartości w celu określenia interwału czasu.

WaitAll(WaitHandle[], Int32)

Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu Int32 wartości w celu określenia interwału czasu.

WaitAll(WaitHandle[])

Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy.

WaitAll(WaitHandle[], TimeSpan, Boolean)

Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs

Czeka na odbieranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu TimeSpan wartości w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

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[]

Tablica WaitHandle zawierająca obiekty, dla których będzie czekać bieżące wystąpienie. Ta tablica nie może zawierać wielu odwołań do tego samego obiektu.

timeout
TimeSpan

Element TimeSpan reprezentujący liczbę milisekund oczekiwania lub wartość reprezentującą TimeSpan -1 milisekundy, aby czekać na czas nieokreślony.

exitContext
Boolean

true aby zamknąć domenę synchronizacji dla kontekstu przed oczekiwaniem (jeśli w zsynchronizowanym kontekście) i ponownie go później; w przeciwnym razie , false.

Zwraca

true gdy każdy element w waitHandles elemecie otrzymał sygnał; w przeciwnym razie false.

Wyjątki

Parametr waitHandles to null.

-lub-

Co najmniej jeden obiekt w tablicy waitHandles to null.

-lub-

waitHandlesjest tablicą bez elementów, a wersja .NET Framework to 2.0 lub nowsza.

Tablica waitHandles zawiera elementy, które są duplikatami.

Liczba obiektów w obiekcie waitHandles jest większa niż zezwala system.

-lub-

Atrybut STAThreadAttribute jest stosowany do procedury wątku dla bieżącego wątku i waitHandles zawiera więcej niż jeden element.

waitHandlesjest tablicą bez elementów, a wersja .NET Framework to 1.0 lub 1.1.

timeout jest liczbą ujemną inną niż -1 milisekund, która reprezentuje nieskończony limit czasu.

-lub-

timeout wartość jest większa niż Int32.MaxValue.

Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.

Tablica waitHandles zawiera przezroczysty serwer proxy dla WaitHandle innej domeny aplikacji.

Przykłady

Poniższy przykład kodu pokazuje, jak używać puli wątków do asynchronicznego tworzenia i zapisywania w grupie plików. Każda operacja zapisu jest w kolejce jako element roboczy i sygnały po zakończeniu. Główny wątek czeka na sygnał wszystkich elementów, a następnie kończy działanie.

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

Uwagi

Jeśli timeout jest zero, metoda nie blokuje. Testuje stan uchwytów oczekiwania i zwraca natychmiast.

Jeśli mutex zostanie porzucony, AbandonedMutexException zostanie zgłoszony. Porzucony mutex często wskazuje poważny błąd kodowania. W przypadku mutexu całego systemu może to oznaczać, że aplikacja została nagle zakończona (na przykład przy użyciu Menedżera zadań systemu Windows). Wyjątek zawiera informacje przydatne do debugowania.

Metoda WaitAll zwraca wartość po zakończeniu oczekiwania, co oznacza, że wszystkie uchwyty są sygnalizowane lub występuje przekroczenie limitu czasu. Jeśli przekazano więcej niż 64 uchwyty, NotSupportedException zostanie zwrócona wartość . Jeśli tablica zawiera duplikaty, wywołanie zakończy się niepowodzeniem.

Uwaga

Metoda nie jest obsługiwana WaitAll w wątkach w STA stanie.

Wartość maksymalna to timeoutInt32.MaxValue.

Zamykanie kontekstu

Parametr exitContext nie ma wpływu, chyba że ta metoda jest wywoływana z wewnątrz kontekstu zarządzanego niezdefault. Kontekst zarządzany może być niezdefault, jeśli wątek znajduje się wewnątrz wywołania wystąpienia klasy pochodzącej z ContextBoundObjectklasy . Nawet jeśli obecnie wykonujesz metodę w klasie, która nie pochodzi z ContextBoundObjectklasy , na przykład String, możesz być w kontekście niezdefault, jeśli element ContextBoundObject znajduje się na stosie w bieżącej domenie aplikacji.

Gdy kod jest wykonywany w kontekście niezdefinicyjnym, określając true przyczynę exitContext zakończenia kontekstu zarządzanego niezdefault (czyli przejścia do kontekstu domyślnego) przed wykonaniem tej metody. Wątek powraca do oryginalnego kontekstu niezdefault po zakończeniu wywołania tej metody.

Zamknięcie kontekstu może być przydatne, gdy klasa powiązana z kontekstem SynchronizationAttribute ma atrybut . W takim przypadku wszystkie wywołania do składowych klasy są automatycznie synchronizowane, a domena synchronizacji to cała treść kodu dla klasy. Jeśli kod w stosie wywołań elementu członkowskiego wywołuje tę metodę i określa true dla exitContextelementu , wątek zamyka domenę synchronizacji, co umożliwia wątkowi zablokowanemu wywołanie do dowolnego elementu członkowskiego obiektu. Gdy ta metoda zostanie zwrócona, wątek, który wykonał wywołanie, musi poczekać na ponowne włączenie domeny synchronizacji.

Dotyczy

WaitAll(WaitHandle[], Int32, Boolean)

Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs

Czeka, aż wszystkie elementy w określonej tablicy otrzymają sygnał, używając Int32 wartości w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

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[]

Tablica WaitHandle zawierająca obiekty, dla których będzie czekać bieżące wystąpienie. Ta tablica nie może zawierać wielu odwołań do tego samego obiektu (duplikaty).

millisecondsTimeout
Int32

Liczba milisekund oczekiwania lub Infinite (-1) na czas nieokreślony.

exitContext
Boolean

true aby zamknąć domenę synchronizacji dla kontekstu przed oczekiwaniem (jeśli w zsynchronizowanym kontekście) i ponownie go później; w przeciwnym razie , false.

Zwraca

true gdy każdy element w waitHandles elemecie otrzymał sygnał; falsew przeciwnym razie .

Wyjątki

Parametr waitHandles to null.

-lub-

Co najmniej jeden obiekt w tablicy waitHandles to null.

-lub-

waitHandlesjest tablicą bez elementów, a wersja .NET Framework to 2.0 lub nowsza.

Tablica waitHandles zawiera elementy, które są duplikatami.

Liczba obiektów w obiekcie waitHandles jest większa niż zezwala system.

-lub-

Bieżący wątek jest w STA stanie i waitHandles zawiera więcej niż jeden element.

waitHandlesjest tablicą bez elementów, a wersja .NET Framework to 1.0 lub 1.1.

millisecondsTimeout jest liczbą ujemną inną niż -1, która reprezentuje nieskończony limit czasu.

Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.

Tablica waitHandles zawiera przezroczysty serwer proxy dla WaitHandle innej domeny aplikacji.

Przykłady

Poniższy przykład kodu pokazuje, jak używać puli wątków do asynchronicznego tworzenia i zapisywania w grupie plików. Każda operacja zapisu jest w kolejce jako element roboczy i sygnały po zakończeniu. Główny wątek czeka na sygnał wszystkich elementów, a następnie kończy działanie.

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

Uwagi

Jeśli millisecondsTimeout jest zero, metoda nie blokuje. Testuje stan uchwytów oczekiwania i zwraca natychmiast.

Jeśli mutex zostanie porzucony, AbandonedMutexException zostanie zgłoszony. Porzucony mutex często wskazuje poważny błąd kodowania. W przypadku mutexu całego systemu może to oznaczać, że aplikacja została nagle zakończona (na przykład przy użyciu Menedżera zadań systemu Windows). Wyjątek zawiera informacje przydatne do debugowania.

Metoda WaitAll zwraca wartość po zakończeniu oczekiwania, co oznacza, że gdy wszystkie uchwyty są sygnalizowane lub gdy wystąpi limit czasu. Jeśli przekazano więcej niż 64 uchwyty, NotSupportedException zostanie zwrócona wartość . Jeśli w tablicy występują duplikaty, wywołanie kończy się niepowodzeniem z parametrem DuplicateWaitObjectException.

Uwaga

Metoda nie jest obsługiwana WaitAll w wątkach w STA stanie.

Zamykanie kontekstu

Parametr exitContext nie ma wpływu, chyba że ta metoda jest wywoływana z wewnątrz kontekstu zarządzanego niezdefault. Kontekst zarządzany może być niezdefault, jeśli wątek znajduje się wewnątrz wywołania wystąpienia klasy pochodzącej z ContextBoundObjectklasy . Nawet jeśli obecnie wykonujesz metodę w klasie, która nie pochodzi z ContextBoundObjectklasy , na przykład String, możesz być w kontekście niezdefault, jeśli element ContextBoundObject znajduje się na stosie w bieżącej domenie aplikacji.

Gdy kod jest wykonywany w kontekście niezdefinicyjnym, określając true przyczynę exitContext zakończenia kontekstu zarządzanego niezdefault (czyli przejścia do kontekstu domyślnego) przed wykonaniem tej metody. Wątek powraca do oryginalnego kontekstu niezdefault po zakończeniu wywołania tej metody.

Zamknięcie kontekstu może być przydatne, gdy klasa powiązana z kontekstem SynchronizationAttribute ma atrybut . W takim przypadku wszystkie wywołania do składowych klasy są automatycznie synchronizowane, a domena synchronizacji to cała treść kodu dla klasy. Jeśli kod w stosie wywołań elementu członkowskiego wywołuje tę metodę i określa true dla exitContextelementu , wątek zamyka domenę synchronizacji, co umożliwia wątkowi zablokowanemu wywołanie do dowolnego elementu członkowskiego obiektu. Gdy ta metoda zostanie zwrócona, wątek, który wykonał wywołanie, musi poczekać na ponowne włączenie domeny synchronizacji.

Dotyczy

WaitAll(WaitHandle[], TimeSpan)

Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs

Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu TimeSpan wartości w celu określenia interwału czasu.

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[]

Tablica WaitHandle zawierająca obiekty, dla których będzie czekać bieżące wystąpienie. Ta tablica nie może zawierać wielu odwołań do tego samego obiektu.

timeout
TimeSpan

Element TimeSpan reprezentujący liczbę milisekund oczekiwania lub wartość reprezentującą TimeSpan -1 milisekundy, aby czekać na czas nieokreślony.

Zwraca

true gdy każdy element w waitHandles elemecie otrzymał sygnał; falsew przeciwnym razie .

Wyjątki

Parametr waitHandles to null.

-lub-

Co najmniej jeden obiekt w tablicy waitHandles to null.

-lub-

waitHandles jest tablicą bez elementów.

Tablica waitHandles zawiera elementy, które są duplikatami.

Uwaga: na platformie .NET dla aplikacji ze Sklepu Windows lub w przenośnej bibliotece klas przechwyć wyjątek klasy bazowej , ArgumentExceptionzamiast tego.

Liczba obiektów w obiekcie waitHandles jest większa niż zezwala system.

-lub-

Bieżący wątek jest w STA stanie i waitHandles zawiera więcej niż jeden element.

timeout jest liczbą ujemną inną niż -1 milisekund, która reprezentuje nieskończony limit czasu.

-lub-

timeout wartość jest większa niż Int32.MaxValue.

Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.

Tablica waitHandles zawiera przezroczysty serwer proxy dla WaitHandle innej domeny aplikacji.

Uwagi

Jeśli timeout jest zero, metoda nie blokuje. Testuje stan uchwytów oczekiwania i zwraca natychmiast.

Metoda WaitAll zwraca wartość po zakończeniu oczekiwania, co oznacza, że wszystkie uchwyty są sygnalizowane lub występuje przekroczenie limitu czasu. Jeśli przekazano więcej niż 64 uchwyty, NotSupportedException zostanie zwrócona wartość . Jeśli tablica zawiera duplikaty, wywołanie zakończy się niepowodzeniem.

Uwaga

Metoda nie jest obsługiwana WaitAll w wątkach w STA stanie.

Wartość maksymalna to timeoutInt32.MaxValue.

Wywoływanie tego przeciążenia metody jest takie samo, jak wywoływanie WaitAll(WaitHandle[], TimeSpan, Boolean) przeciążenia i określanie false wartości .exitContext

Dotyczy

WaitAll(WaitHandle[], Int32)

Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs

Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy przy użyciu Int32 wartości w celu określenia interwału czasu.

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[]

Tablica WaitHandle zawierająca obiekty, dla których będzie czekać bieżące wystąpienie. Ta tablica nie może zawierać wielu odwołań do tego samego obiektu (duplikaty).

millisecondsTimeout
Int32

Liczba milisekund oczekiwania lub Infinite (-1) na czas nieokreślony.

Zwraca

true gdy każdy element w waitHandles elemecie otrzymał sygnał; falsew przeciwnym razie .

Wyjątki

Parametr waitHandles to null.

-lub-

Co najmniej jeden obiekt w tablicy waitHandles to null.

-lub-

waitHandles jest tablicą bez elementów.

Tablica waitHandles zawiera elementy, które są duplikatami.

Uwaga: na platformie .NET dla aplikacji ze Sklepu Windows lub w przenośnej bibliotece klas przechwyć wyjątek klasy bazowej , ArgumentExceptionzamiast tego.

Liczba obiektów w obiekcie waitHandles jest większa niż zezwala system.

-lub-

Bieżący wątek jest w STA stanie i waitHandles zawiera więcej niż jeden element.

millisecondsTimeout jest liczbą ujemną inną niż -1, która reprezentuje nieskończony limit czasu.

Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.

Tablica waitHandles zawiera przezroczysty serwer proxy dla WaitHandle innej domeny aplikacji.

Uwagi

Jeśli millisecondsTimeout jest zero, metoda nie blokuje. Testuje stan uchwytów oczekiwania i zwraca natychmiast.

Metoda WaitAll zwraca wartość po zakończeniu oczekiwania, co oznacza, że gdy wszystkie uchwyty są sygnalizowane lub gdy wystąpi limit czasu. Jeśli przekazano więcej niż 64 uchwyty, NotSupportedException zostanie zwrócona wartość . Jeśli w tablicy występują duplikaty, wywołanie kończy się niepowodzeniem z parametrem DuplicateWaitObjectException.

Uwaga

Metoda nie jest obsługiwana WaitAll w wątkach w STA stanie.

Wywoływanie tego przeciążenia metody jest takie samo, jak wywoływanie WaitAll(WaitHandle[], Int32, Boolean) przeciążenia i określanie false wartości .exitContext

Dotyczy

WaitAll(WaitHandle[])

Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs

Czeka na odebranie sygnału przez wszystkie elementy w określonej tablicy.

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[]

Tablica WaitHandle zawierająca obiekty, dla których będzie czekać bieżące wystąpienie. Ta tablica nie może zawierać wielu odwołań do tego samego obiektu.

Zwraca

true gdy każdy element w waitHandles elemecie otrzymał sygnał; w przeciwnym razie metoda nigdy nie zwraca.

Wyjątki

Parametr waitHandles to null. -lub-

Co najmniej jeden obiekt w tablicy waitHandles to null.

-lub-

waitHandlesjest tablicą bez elementów, a wersja .NET Framework to 2.0 lub nowsza.

Tablica waitHandles zawiera elementy, które są duplikatami.

Uwaga: na platformie .NET dla aplikacji ze Sklepu Windows lub w przenośnej bibliotece klas przechwyć wyjątek klasy bazowej , ArgumentExceptionzamiast tego.

Liczba obiektów w obiekcie waitHandles jest większa niż zezwala system.

-lub-

Bieżący wątek jest w STA stanie i waitHandles zawiera więcej niż jeden element.

waitHandlesjest tablicą bez elementów, a wersja .NET Framework to 1.0 lub 1.1.

Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.

Tablica waitHandles zawiera przezroczysty serwer proxy dla WaitHandle innej domeny aplikacji.

Przykłady

Poniższy przykład kodu pokazuje, jak używać puli wątków do asynchronicznego tworzenia i zapisywania w grupie plików. Każda operacja zapisu jest w kolejce jako element roboczy i sygnały po zakończeniu. Główny wątek czeka na sygnał wszystkich elementów, a następnie kończy działanie.

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

Uwagi

AbandonedMutexExceptionjest nowy w wersji .NET Framework 2.0. W poprzednich wersjach metoda zwraca wartość true po WaitAll porzuceniu mutexu. Porzucony mutex często wskazuje poważny błąd kodowania. W przypadku mutexu całego systemu może to oznaczać, że aplikacja została nagle zakończona (na przykład przy użyciu Menedżera zadań systemu Windows). Wyjątek zawiera informacje przydatne do debugowania.

Metoda WaitAll zwraca wartość , gdy wszystkie uchwyty są sygnalizowane. Jeśli przekazano więcej niż 64 uchwyty, NotSupportedException zostanie zwrócona wartość . Jeśli tablica zawiera duplikaty, wywołanie kończy się niepowodzeniem z parametrem DuplicateWaitObjectException.

Uwaga

Metoda nie jest obsługiwana WaitAll w wątkach w STA stanie.

Wywołanie tego przeciążenia metody jest równoważne wywołaniu WaitAll(WaitHandle[], Int32, Boolean) przeciążenia metody i określenie -1 (lub Timeout.Infinite) dla i true dla exitContextmillisecondsTimeout .

Dotyczy