Share via


WaitHandle.WaitAll Metode

Definisi

Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal.

Overload

WaitAll(WaitHandle[], TimeSpan, Boolean)

Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan TimeSpan nilai untuk menentukan interval waktu, dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu.

WaitAll(WaitHandle[], Int32, Boolean)

Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan Int32 nilai untuk menentukan interval waktu dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu.

WaitAll(WaitHandle[], TimeSpan)

Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan TimeSpan nilai untuk menentukan interval waktu.

WaitAll(WaitHandle[], Int32)

Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan Int32 nilai untuk menentukan interval waktu.

WaitAll(WaitHandle[])

Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal.

WaitAll(WaitHandle[], TimeSpan, Boolean)

Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs

Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan TimeSpan nilai untuk menentukan interval waktu, dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu.

public:
 static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout, bool exitContext);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext);
static member WaitAll : System.Threading.WaitHandle[] * TimeSpan * bool -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), timeout As TimeSpan, exitContext As Boolean) As Boolean

Parameter

waitHandles
WaitHandle[]

Array WaitHandle yang berisi objek yang instans saat ini akan menunggu. Array ini tidak boleh berisi beberapa referensi ke objek yang sama.

timeout
TimeSpan

TimeSpan yang menunjukkan jumlah milidetik untuk menunggu, atau TimeSpan yang mewakili -1 milidetik, untuk menunggu tanpa batas waktu.

exitContext
Boolean

true untuk keluar dari domain sinkronisasi untuk konteks sebelum menunggu (jika dalam konteks yang disinkronkan), dan memperolehnya kembali setelahnya; jika tidak, false.

Mengembalikan

true ketika setiap elemen di waitHandles telah menerima sinyal; jika tidak false.

Pengecualian

Parameternya waitHandles adalah null.

-atau-

Satu atau beberapa objek dalam waitHandles array adalah null.

-atau-

waitHandlesadalah array tanpa elemen dan versi .NET Framework adalah 2.0 atau yang lebih baru.

Array waitHandles berisi elemen yang merupakan duplikat.

Jumlah objek di waitHandles lebih besar dari yang diizinkan sistem.

-atau-

Atribut STAThreadAttribute diterapkan ke prosedur utas untuk utas saat ini, dan waitHandles berisi lebih dari satu elemen.

waitHandlesadalah array tanpa elemen dan versi .NET Framework adalah 1.0 atau 1.1.

timeout adalah angka negatif selain -1 milidetik, yang mewakili batas waktu tak terbatas.

-atau-

timeout lebih besar dari Int32.MaxValue.

Penantian dihentikan karena utas keluar tanpa melepaskan mutex.

Array waitHandles berisi proksi transparan untuk WaitHandle di domain aplikasi lain.

Contoh

Contoh kode berikut menunjukkan cara menggunakan kumpulan utas untuk membuat dan menulis secara asinkron ke sekelompok file. Setiap operasi tulis diantrekan sebagai item kerja dan memberi sinyal ketika selesai. Utas utama menunggu semua item memberi sinyal dan kemudian keluar.

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

Keterangan

Jika timeout nol, metode tidak memblokir. Ini menguji status handel tunggu dan segera kembali.

Jika muteks ditinggalkan, akan AbandonedMutexException dilemparkan. Mutex yang ditinggalkan sering menunjukkan kesalahan pengkodian yang serius. Dalam kasus mutex di seluruh sistem, mungkin menunjukkan bahwa aplikasi telah dihentikan tiba-tiba (misalnya, dengan menggunakan Windows Task Manager). Pengecualian berisi informasi yang berguna untuk penelusuran kesalahan.

Metode WaitAll ini kembali ketika waktu tunggu berakhir, yang berarti semua handel diberi sinyal atau waktu habis terjadi. Jika lebih dari 64 handel dilewati, akan NotSupportedException dilemparkan. Jika array berisi duplikat, panggilan akan gagal.

Catatan

Metode WaitAll ini tidak didukung pada utas dalam STA status .

Nilai maksimum untuk timeout adalah Int32.MaxValue.

Keluar dari konteks

Parameter exitContext tidak berpengaruh kecuali metode ini dipanggil dari dalam konteks terkelola nondefault. Konteks terkelola dapat menjadi nondefault jika utas Anda berada di dalam panggilan ke instans kelas yang berasal dari ContextBoundObject. Bahkan jika saat ini Anda menjalankan metode pada kelas yang tidak berasal dari ContextBoundObject, seperti String, Anda dapat berada dalam konteks nondefault jika ContextBoundObject ada di tumpukan Anda di domain aplikasi saat ini.

Saat kode Anda dijalankan dalam konteks nondefault, menentukan true penyebab exitContext utas keluar dari konteks terkelola nondefault (yaitu, untuk beralih ke konteks default) sebelum menjalankan metode ini. Utas kembali ke konteks nondefault asli setelah panggilan ke metode ini selesai.

Keluar dari konteks dapat berguna ketika kelas yang terikat konteks memiliki SynchronizationAttribute atribut . Dalam hal ini, semua panggilan ke anggota kelas secara otomatis disinkronkan, dan domain sinkronisasi adalah seluruh isi kode untuk kelas . Jika kode dalam tumpukan panggilan anggota memanggil metode ini dan menentukan untuk exitContext, utas true keluar dari domain sinkronisasi, yang memungkinkan utas yang diblokir pada panggilan ke anggota objek mana pun untuk melanjutkan. Ketika metode ini kembali, utas yang melakukan panggilan harus menunggu untuk masuk kembali ke domain sinkronisasi.

Berlaku untuk

WaitAll(WaitHandle[], Int32, Boolean)

Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs

Menunggu semua elemen dalam array yang ditentukan menerima sinyal, menggunakan Int32 nilai untuk menentukan interval waktu dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu.

public:
 static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout, bool exitContext);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext);
static member WaitAll : System.Threading.WaitHandle[] * int * bool -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), millisecondsTimeout As Integer, exitContext As Boolean) As Boolean

Parameter

waitHandles
WaitHandle[]

Array WaitHandle yang berisi objek yang instans saat ini akan menunggu. Array ini tidak boleh berisi beberapa referensi ke objek yang sama (duplikat).

millisecondsTimeout
Int32

Jumlah milidetik untuk menunggu, atau Infinite (-1) untuk menunggu tanpa batas waktu.

exitContext
Boolean

true untuk keluar dari domain sinkronisasi untuk konteks sebelum menunggu (jika dalam konteks yang disinkronkan), dan memperolehnya kembali setelahnya; jika tidak, false.

Mengembalikan

true ketika setiap elemen di waitHandles telah menerima sinyal; jika tidak, false.

Pengecualian

Parameternya waitHandles adalah null.

-atau-

Satu atau beberapa objek dalam waitHandles array adalah null.

-atau-

waitHandlesadalah array tanpa elemen dan versi .NET Framework adalah 2.0 atau yang lebih baru.

Array waitHandles berisi elemen yang merupakan duplikat.

Jumlah objek di waitHandles lebih besar dari yang diizinkan sistem.

-atau-

Utas saat ini dalam STA status , dan waitHandles berisi lebih dari satu elemen.

waitHandlesadalah array tanpa elemen dan versi .NET Framework adalah 1.0 atau 1.1.

millisecondsTimeout adalah angka negatif selain -1, yang menunjukkan waktu habis yang tak terbatas.

Penantian selesai karena utas keluar tanpa melepaskan mutex.

Array waitHandles berisi proksi transparan untuk WaitHandle di domain aplikasi lain.

Contoh

Contoh kode berikut menunjukkan cara menggunakan kumpulan utas untuk membuat dan menulis secara asinkron ke sekelompok file. Setiap operasi tulis diantrekan sebagai item kerja dan memberi sinyal ketika selesai. Utas utama menunggu semua item memberi sinyal dan kemudian keluar.

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

Keterangan

Jika millisecondsTimeout nol, metode tidak memblokir. Ini menguji status handel tunggu dan segera kembali.

Jika muteks ditinggalkan, akan AbandonedMutexException dilemparkan. Mutex yang ditinggalkan sering menunjukkan kesalahan pengkodian yang serius. Dalam kasus mutex di seluruh sistem, mungkin menunjukkan bahwa aplikasi telah dihentikan tiba-tiba (misalnya, dengan menggunakan Windows Task Manager). Pengecualian berisi informasi yang berguna untuk penelusuran kesalahan.

Metode WaitAll ini kembali ketika waktu tunggu berakhir, yang berarti baik ketika semua handel diberi sinyal atau ketika waktu habis terjadi. Jika lebih dari 64 handel dilewati, akan NotSupportedException dilemparkan. Jika ada duplikat dalam array, panggilan gagal dengan DuplicateWaitObjectException.

Catatan

Metode WaitAll ini tidak didukung pada utas dalam STA status .

Keluar dari konteks

Parameter exitContext tidak berpengaruh kecuali metode ini dipanggil dari dalam konteks terkelola nondefault. Konteks terkelola dapat menjadi nondefault jika utas Anda berada di dalam panggilan ke instans kelas yang berasal dari ContextBoundObject. Bahkan jika saat ini Anda menjalankan metode pada kelas yang tidak berasal dari ContextBoundObject, seperti String, Anda dapat berada dalam konteks nondefault jika ContextBoundObject ada di tumpukan Anda di domain aplikasi saat ini.

Saat kode Anda dijalankan dalam konteks nondefault, menentukan true penyebab exitContext utas keluar dari konteks terkelola nondefault (yaitu, untuk beralih ke konteks default) sebelum menjalankan metode ini. Utas kembali ke konteks nondefault asli setelah panggilan ke metode ini selesai.

Keluar dari konteks dapat berguna ketika kelas yang terikat konteks memiliki SynchronizationAttribute atribut . Dalam hal ini, semua panggilan ke anggota kelas secara otomatis disinkronkan, dan domain sinkronisasi adalah seluruh isi kode untuk kelas . Jika kode dalam tumpukan panggilan anggota memanggil metode ini dan menentukan untuk exitContext, utas true keluar dari domain sinkronisasi, yang memungkinkan utas yang diblokir pada panggilan ke anggota objek mana pun untuk melanjutkan. Ketika metode ini kembali, utas yang melakukan panggilan harus menunggu untuk masuk kembali ke domain sinkronisasi.

Berlaku untuk

WaitAll(WaitHandle[], TimeSpan)

Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs

Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan TimeSpan nilai untuk menentukan interval waktu.

public:
 static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout);
static member WaitAll : System.Threading.WaitHandle[] * TimeSpan -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), timeout As TimeSpan) As Boolean

Parameter

waitHandles
WaitHandle[]

Array WaitHandle yang berisi objek tempat instans saat ini akan menunggu. Array ini tidak boleh berisi beberapa referensi ke objek yang sama.

timeout
TimeSpan

TimeSpan yang mewakili jumlah milidetik untuk menunggu, atau TimeSpan yang mewakili -1 milidetik, untuk menunggu tanpa batas waktu.

Mengembalikan

true ketika setiap elemen di waitHandles telah menerima sinyal; jika tidak, false.

Pengecualian

Parameternya waitHandles adalah null.

-atau-

Satu atau beberapa objek dalam waitHandles array adalah null.

-atau-

waitHandles adalah array tanpa elemen.

Array waitHandles berisi elemen yang merupakan duplikat.

Catatan: Di .NET untuk aplikasi Bursa Windows atau Pustaka Kelas Portabel, tangkap pengecualian kelas dasar, ArgumentException, sebagai gantinya.

Jumlah objek di waitHandles lebih besar dari yang diizinkan sistem.

-atau-

Utas saat ini dalam STA status , dan waitHandles berisi lebih dari satu elemen.

timeout adalah angka negatif selain -1 milidetik, yang mewakili waktu habis yang tak terbatas.

-atau-

timeout lebih besar dari Int32.MaxValue.

Penantian dihentikan karena utas keluar tanpa melepaskan mutex.

Array waitHandles berisi proksi transparan untuk WaitHandle di domain aplikasi lain.

Keterangan

Jika timeout nol, metode tidak memblokir. Ini menguji status handel tunggu dan segera kembali.

Metode WaitAll ini kembali ketika waktu tunggu berakhir, yang berarti semua handel diberi sinyal atau waktu habis terjadi. Jika lebih dari 64 handel diteruskan, akan NotSupportedException dilemparkan. Jika array berisi duplikat, panggilan akan gagal.

Catatan

Metode WaitAll ini tidak didukung pada utas dalam STA status.

Nilai maksimum untuk timeout adalah Int32.MaxValue.

Memanggil metode ini kelebihan beban sama dengan memanggil WaitAll(WaitHandle[], TimeSpan, Boolean) kelebihan beban dan menentukan false untuk exitContext.

Berlaku untuk

WaitAll(WaitHandle[], Int32)

Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs

Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal, menggunakan Int32 nilai untuk menentukan interval waktu.

public:
 static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout);
static member WaitAll : System.Threading.WaitHandle[] * int -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), millisecondsTimeout As Integer) As Boolean

Parameter

waitHandles
WaitHandle[]

Array WaitHandle yang berisi objek tempat instans saat ini akan menunggu. Array ini tidak boleh berisi beberapa referensi ke objek yang sama (duplikat).

millisecondsTimeout
Int32

Jumlah milidetik untuk menunggu, atau Infinite (-1) untuk menunggu tanpa batas waktu.

Mengembalikan

true ketika setiap elemen di waitHandles telah menerima sinyal; jika tidak, false.

Pengecualian

Parameternya waitHandles adalah null.

-atau-

Satu atau beberapa objek dalam waitHandles array adalah null.

-atau-

waitHandles adalah array tanpa elemen.

Array waitHandles berisi elemen yang merupakan duplikat.

Catatan: Di .NET untuk aplikasi Bursa Windows atau Pustaka Kelas Portabel, tangkap pengecualian kelas dasar, ArgumentException, sebagai gantinya.

Jumlah objek di waitHandles lebih besar dari yang diizinkan sistem.

-atau-

Utas saat ini dalam STA status , dan waitHandles berisi lebih dari satu elemen.

millisecondsTimeout adalah angka negatif selain -1, yang mewakili waktu habis yang tak terbatas.

Penantian selesai karena utas keluar tanpa melepaskan mutex.

Array waitHandles berisi proksi transparan untuk WaitHandle di domain aplikasi lain.

Keterangan

Jika millisecondsTimeout nol, metode tidak memblokir. Ini menguji status handel tunggu dan segera kembali.

Metode WaitAll ini kembali ketika waktu tunggu berakhir, yang berarti ketika semua handel diberi sinyal atau ketika waktu habis terjadi. Jika lebih dari 64 handel diteruskan, akan NotSupportedException dilemparkan. Jika ada duplikat dalam array, panggilan gagal dengan DuplicateWaitObjectException.

Catatan

Metode WaitAll ini tidak didukung pada utas dalam STA status.

Memanggil metode ini kelebihan beban sama dengan memanggil WaitAll(WaitHandle[], Int32, Boolean) kelebihan beban dan menentukan false untuk exitContext.

Berlaku untuk

WaitAll(WaitHandle[])

Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs
Sumber:
WaitHandle.cs

Menunggu semua elemen dalam array yang ditentukan untuk menerima sinyal.

public:
 static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles);
static member WaitAll : System.Threading.WaitHandle[] -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle()) As Boolean

Parameter

waitHandles
WaitHandle[]

Array WaitHandle yang berisi objek tempat instans saat ini akan menunggu. Array ini tidak boleh berisi beberapa referensi ke objek yang sama.

Mengembalikan

true ketika setiap elemen di waitHandles telah menerima sinyal; jika tidak, metode tidak pernah kembali.

Pengecualian

Parameternya waitHandles adalah null. -atau-

Satu atau beberapa objek dalam waitHandles array adalah null.

-atau-

waitHandlesadalah array tanpa elemen dan versi .NET Framework adalah 2.0 atau yang lebih baru.

Array waitHandles berisi elemen yang merupakan duplikat.

Catatan: Di .NET untuk aplikasi Bursa Windows atau Pustaka Kelas Portabel, tangkap pengecualian kelas dasar, ArgumentException, sebagai gantinya.

Jumlah objek di waitHandles lebih besar dari yang diizinkan sistem.

-atau-

Utas saat ini dalam STA status , dan waitHandles berisi lebih dari satu elemen.

waitHandlesadalah array tanpa elemen dan versi .NET Framework adalah 1.0 atau 1.1.

Penantian dihentikan karena utas keluar tanpa melepaskan mutex.

Array waitHandles berisi proksi transparan untuk WaitHandle di domain aplikasi lain.

Contoh

Contoh kode berikut menunjukkan cara menggunakan kumpulan utas untuk membuat dan menulis secara asinkron ke sekelompok file. Setiap operasi tulis diantrekan sebagai item kerja dan memberi sinyal ketika selesai. Utas utama menunggu semua item untuk memberi sinyal dan kemudian keluar.

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

Keterangan

AbandonedMutexExceptionbaru dalam .NET Framework versi 2.0. Di versi sebelumnya, WaitAll metode akan kembali true saat mutex ditinggalkan. Mutex yang ditinggalkan sering menunjukkan kesalahan pengkodian yang serius. Dalam kasus mutex di seluruh sistem, mungkin menunjukkan bahwa aplikasi telah dihentikan tiba-tiba (misalnya, dengan menggunakan Windows Task Manager). Pengecualian berisi informasi yang berguna untuk penelusuran kesalahan.

Metode WaitAll mengembalikan ketika semua handel diberi sinyal. Jika lebih dari 64 handel diteruskan, akan NotSupportedException dilemparkan. Jika array berisi duplikat, panggilan gagal dengan DuplicateWaitObjectException.

Catatan

Metode WaitAll ini tidak didukung pada utas dalam STA status.

Memanggil metode ini kelebihan beban setara dengan memanggil WaitAll(WaitHandle[], Int32, Boolean) metode kelebihan beban dan menentukan -1 (atau Timeout.Infinite) untuk millisecondsTimeout dan true untuk exitContext.

Berlaku untuk