WaitHandle.WaitAny メソッド (WaitHandle , Int32, Boolean)
32 ビットの符号付き整数を使用して時間間隔を計測し、待機する前に同期ドメインを終了するかどうかを指定して、指定した配列内のいずれかの要素がシグナルを受信するまで待機します。
Overloads Public Shared Function WaitAny( _
ByVal waitHandles() As WaitHandle, _ ByVal millisecondsTimeout As Integer, _ ByVal exitContext As Boolean _) As Integer
[C#]
public static int WaitAny(WaitHandle[] waitHandles,intmillisecondsTimeout,boolexitContext);
[C++]
public: static int WaitAny(WaitHandle* waitHandles[],intmillisecondsTimeout,boolexitContext);
[JScript]
public static function WaitAny(
waitHandles : WaitHandle[],millisecondsTimeout : int,exitContext : Boolean) : int;
パラメータ
- waitHandles
現在のインスタンスが待機する対象のオブジェクトを格納している WaitHandle 配列。 - millisecondsTimeout
待機するミリ秒数。無制限に待機する場合は Timeout.Infinite (-1)。 - exitContext
待機する前にコンテキストの同期ドメインを終了し (同期されたコンテキストの場合)、再び取得する場合は true 。それ以外の場合は false 。
戻り値
待機を実行したオブジェクトの配列インデックス。つまり、待機を実行したオブジェクトがない場合や millisecondsTimeout で渡された時間間隔と等しい場合は WaitTimeout となります。
例外
例外の種類 | 条件 |
---|---|
ArgumentNullException | waitHandles パラメータが null 参照 (Visual Basic では Nothing) であるか、 waitHandles 配列内の 1 つ以上のオブジェクトが null 参照 (Nothing) です。 |
NotSupportedException | waitHandles 内のオブジェクト数がシステムによって許可されている数を超えています。 |
ApplicationException | waitHandles が要素のない配列です。 |
ArgumentOutOfRangeException | millisecondsTimeout が -1 以外の負数です。-1 は無制限のタイムアウトを表します。 |
解説
このメソッドは、待機が終了するとき、ハンドルのいずれかがシグナル状態になるとき、またはタイムアウトが発生するときに制御を返します。複数のオブジェクトが呼び出し中にシグナル状態になった場合、戻り値はすべてのシグナル状態オブジェクトのうち、最小インデックス値を持つシグナル状態オブジェクトの配列インデックスになります。一部の実装では、64 個を超えるハンドルが渡されると、 NotSupportedException がスローされます。配列に重複が含まれていると、呼び出しは失敗します。
メモ スレッドが Mutex を明示的に解放せず終了するか中止し、 Mutex が別のスレッドの WaitAny に含まれている場合、 WaitAny で返されるインデックスは、正しい値に 128 を足した値になります。これを防止するには、このメソッドを使用する前にインデックスを確認してください。インデックスの確認には、C# コードの場合は
if (index >= 128) index -= 128;
などを使用し、Visual Basic コードの場合はIf index >= 128 Then index -= 128
などを使用します。
使用例
[Visual Basic, C#, C++] スレッド プールを使用して、ファイルを複数のディスク上で同時に検索する方法の例を次に示します。ここでは、各ディスクのルート ディレクトリだけを検索します。
Imports Microsoft.VisualBasic
Imports System
Imports System.IO
Imports System.Threading
Public Class Test
Shared Sub Main()
Dim search As New Search()
search.FindFile("SomeFile.dat")
End Sub
End Class
Public Class Search
' Maintain state information to pass to FindCallback.
Class State
Public autoEvent As AutoResetEvent
Public fileName As String
Sub New(anEvent As AutoResetEvent, fName As String)
autoEvent = anEvent
fileName = fName
End Sub
End Class
Dim autoEvents() As AutoResetEvent
Dim diskLetters() As String
Sub New()
' Retrieve an array of disk letters.
diskLetters = Environment.GetLogicalDrives()
autoEvents = New AutoResetEvent(diskLetters.Length - 1) {}
For i As Integer = 0 To diskLetters.Length - 1
autoEvents(i) = New AutoResetEvent(False)
Next i
End Sub
' Search for fileName in the root directory of all disks.
Sub FindFile(fileName As String)
For i As Integer = 0 To diskLetters.Length - 1
Console.WriteLine("Searching for {0} on {1}.", _
fileName, diskLetters(i))
ThreadPool.QueueUserWorkItem(AddressOf FindCallback, _
New State(autoEvents(i), diskLetters(i) & fileName))
Next i
' Wait for the first instance of the file to be found.
Dim index As Integer = _
WaitHandle.WaitAny(autoEvents, 3000, False)
If index = WaitHandle.WaitTimeout
Console.WriteLine(vbCrLf & "{0} not found.", fileName)
Else
Console.WriteLine(vbCrLf & "{0} found on {1}.", _
fileName, diskLetters(index))
End If
End Sub
' Search for stateInfo.fileName.
Sub FindCallback(state As Object)
Dim stateInfo As State = DirectCast(state, State)
' Signal if the file is found.
If File.Exists(stateInfo.fileName) Then
stateInfo.autoEvent.Set()
End If
End Sub
End Class
[C#]
using System;
using System.IO;
using System.Threading;
class Test
{
static void Main()
{
Search search = new Search();
search.FindFile("SomeFile.dat");
}
}
class Search
{
// Maintain state information to pass to FindCallback.
class State
{
public AutoResetEvent autoEvent;
public string fileName;
public State(AutoResetEvent autoEvent, string fileName)
{
this.autoEvent = autoEvent;
this.fileName = fileName;
}
}
AutoResetEvent[] autoEvents;
String[] diskLetters;
public Search()
{
// Retrieve an array of disk letters.
diskLetters = Environment.GetLogicalDrives();
autoEvents = new AutoResetEvent[diskLetters.Length];
for(int i = 0; i < diskLetters.Length; i++)
{
autoEvents[i] = new AutoResetEvent(false);
}
}
// Search for fileName in the root directory of all disks.
public void FindFile(string fileName)
{
for(int i = 0; i < diskLetters.Length; i++)
{
Console.WriteLine("Searching for {0} on {1}.",
fileName, diskLetters[i]);
ThreadPool.QueueUserWorkItem(
new WaitCallback(FindCallback),
new State(autoEvents[i], diskLetters[i] + fileName));
}
// Wait for the first instance of the file to be found.
int index = WaitHandle.WaitAny(autoEvents, 3000, false);
if(index == WaitHandle.WaitTimeout)
{
Console.WriteLine("\n{0} not found.", fileName);
}
else
{
Console.WriteLine("\n{0} found on {1}.", fileName,
diskLetters[index]);
}
}
// Search for stateInfo.fileName.
void FindCallback(object state)
{
State stateInfo = (State)state;
// Signal if the file is found.
if(File.Exists(stateInfo.fileName))
{
stateInfo.autoEvent.Set();
}
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
using namespace System::IO;
using namespace System::Threading;
__gc class Search
{
// Maintain state information to pass to FindCallback.
__gc class State
{
public:
AutoResetEvent* autoEvent;
String* fileName;
State(AutoResetEvent* autoEvent, String* fileName) :
autoEvent(autoEvent), fileName(fileName) {}
};
AutoResetEvent* autoEvents __gc[];
String* diskLetters __gc[];
// Search for stateInfo->fileName.
void FindCallback(Object* state)
{
State* stateInfo = dynamic_cast<State*>(state);
// Signal if the file is found.
if(File::Exists(stateInfo->fileName))
{
stateInfo->autoEvent->Set();
}
}
public:
Search()
{
// Retrieve an array of disk letters.
diskLetters = Environment::GetLogicalDrives();
autoEvents = new AutoResetEvent* __gc[diskLetters->Length];
for(int i = 0; i < diskLetters->Length; i++)
{
autoEvents[i] = new AutoResetEvent(false);
}
}
// Search for fileName in the root directory of all disks.
void FindFile(String* fileName)
{
for(int i = 0; i < diskLetters->Length; i++)
{
Console::WriteLine("Searching for {0} on {1}.",
fileName, diskLetters[i]);
ThreadPool::QueueUserWorkItem(new WaitCallback(
this, &Search::FindCallback), new State(autoEvents[i],
String::Concat(diskLetters[i], fileName)));
}
// Wait for the first instance of the file to be found.
int index = WaitHandle::WaitAny(autoEvents, 3000, false);
if(index == WaitHandle::WaitTimeout)
{
Console::WriteLine(S"\n{0} not found.", fileName);
}
else
{
Console::WriteLine(S"\n{0} found on {1}.", fileName,
diskLetters[index]);
}
}
};
void main()
{
Search* search = new Search();
search->FindFile(S"SomeFile.dat");
}
[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 ファミリ
参照
WaitHandle クラス | WaitHandle メンバ | System.Threading 名前空間 | WaitHandle.WaitAny オーバーロードの一覧