次の方法で共有


WaitHandle.WaitAll メソッド (WaitHandle )

指定した配列内のすべての要素がシグナルを受信するまで待機します。

Overloads Public Shared Function WaitAll( _
   ByVal waitHandles() As WaitHandle _) As Boolean
[C#]
public static bool WaitAll(WaitHandle[] waitHandles);
[C++]
public: static bool WaitAll(WaitHandle* waitHandles[]);
[JScript]
public static function WaitAll(
   waitHandles : WaitHandle[]) : Boolean;

パラメータ

  • waitHandles
    現在のインスタンスが待機する対象のオブジェクトを格納している WaitHandle 配列。この配列には、同一オブジェクトに対する複数の参照 (重複) を含めることはできません。

戻り値

waitHandles 内のすべての要素がシグナルを受信した場合は true 。それ以外の場合は、待機を続けます。

例外

例外の種類 条件
ArgumentNullException waitHandles パラメータが null 参照 (Visual Basic では Nothing) か、または waitHandles 配列にある 1 つ以上のオブジェクトが null 参照 (Nothing) です。
DuplicateWaitObjectException waitHandles 配列に、重複する要素が格納されています。
NotSupportedException waitHandles 内のオブジェクト数がシステムによって許可されている数を超えています。

または

現在のスレッドが STAThreadAttribute でマークされており、 waitHandles 内に複数の要素があります。

ApplicationException waitHandles が要素のない配列です。

解説

すべてのハンドルがシグナルを受信すると待機を終了します。一部の実装では、64 個を超えるハンドルが渡されると、 NotSupportedException がスローされます。配列に重複が含まれていると、呼び出しは失敗します。

メモ   WaitAll メソッドは、 STAThreadAttribute でマークされているスレッドではサポートされません。

このオーバーロードを呼び出すことは、 WaitAll(WaitHandle[],Int32,Boolean) オーバーロードの 2 番目のパラメータに -1 または Timeout.Infinite を指定し、3 番目のパラメータに false を指定して呼び出すことと同じです。

使用例

[Visual Basic, C#, C++] スレッド プールを使用して、ファイルのグループの作成と、そのグループへの書き込みを非同期的に行う方法の例を次に示します。各書き込み操作は、作業項目としてキューに置かれ、終了すると通知を送信します。メイン スレッドは、すべての項目からの通知を待って終了します。

 
Imports System
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading

' Request permission to create and write files to C:\TestTest.
<Assembly: FileIOPermissionAttribute(SecurityAction.RequestMinimum, _
     All := "C:\TestTest")>

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

[C#] 
using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;

// Request permission to create and write files to C:\TestTest.
[assembly: FileIOPermissionAttribute(SecurityAction.RequestMinimum, 
     All = @"C:\TestTest")]

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();
        }
    }
}

[C++] 
#using <mscorlib.dll>
using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;

// Request permission to create and write files to C:\TestTest.
[assembly: FileIOPermissionAttribute(SecurityAction::RequestMinimum, 
     All = "C:\\TestTest")];

// Maintain state to pass to WriteToFile.
__gc class State
{
public:
    String* fileName;
    Byte byteArray __gc [];
    ManualResetEvent* manualEvent;

    State(String* fileName, Byte byteArray __gc [], 
        ManualResetEvent* manualEvent) : fileName(fileName), 
        byteArray(byteArray), manualEvent(manualEvent) {}
};

__gc class Writer
{
    static int workItemCount = 0;
    Writer() {}

public:
    static void WriteToFile(Object* state)
    {
        int workItemNumber = workItemCount;
        Interlocked::Increment(&workItemCount);
        Console::WriteLine(S"Starting work item {0}.", 
            workItemNumber.ToString());
        State* stateInfo = dynamic_cast<State*>(state);
        FileStream* fileWriter;

        // 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 != 0)
            {
                fileWriter->Close();
            }

            // Signal main() that the work item has finished.
            Console::WriteLine(S"Ending work item {0}.", 
                workItemNumber.ToString());
            stateInfo->manualEvent->Set();
        }
    }
};

void main()
{
    const int numberOfFiles = 5;
    String* dirName = "C:\\TestTest";
    String* fileName;

    Byte byteArray __gc [];
    Random* randomGenerator = new Random();

    ManualResetEvent* manualEvents __gc [] = 
        new ManualResetEvent* __gc [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 __gc [1000000];
        randomGenerator->NextBytes(byteArray);

        manualEvents[i] = new ManualResetEvent(false);

        stateInfo = new State(fileName, byteArray, manualEvents[i]);

        ThreadPool::QueueUserWorkItem(new WaitCallback(
            0, &Writer::WriteToFile), stateInfo);
    }
    
    // Since ThreadPool threads are background threads, 
    // wait for the work items to signal before exiting.
    WaitHandle::WaitAll(manualEvents);
    Console::WriteLine(S"Files written - main exiting.");
}

[JScript] JScript のサンプルはありません。Visual Basic、C#、および C++ のサンプルを表示するには、このページの左上隅にある言語のフィルタ ボタン 言語のフィルタ をクリックします。

必要条件

プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ, Common Language Infrastructure (CLI) Standard

参照

WaitHandle クラス | WaitHandle メンバ | System.Threading 名前空間 | WaitHandle.WaitAll オーバーロードの一覧