Pulse メソッドまたは PulseAll メソッドを呼び出したオブジェクトからの通知が行われるまで、または指定した時間が経過するまで待機します。このメソッドは、コンテキストの同期ドメイン (同期されたコンテキストの場合) が待機の前に終了し、再取得されるかどうかも指定します。
Overloads Public Shared Function Wait( _
ByVal obj As Object, _ ByVal millisecondsTimeout As Integer, _ ByVal exitContext As Boolean _) As Boolean
[C#]
public static bool Wait(objectobj,intmillisecondsTimeout,boolexitContext);
[C++]
public: static bool Wait(Object* obj,intmillisecondsTimeout,boolexitContext);
[JScript]
public static function Wait(
obj : Object,millisecondsTimeout : int,exitContext : Boolean) : Boolean;
パラメータ
- obj
待機を行うオブジェクト。 - millisecondsTimeout
メソッドから制御が戻るまで待機するミリ秒単位の時間。 - exitContext
待機の前にコンテキストの同期ドメイン (同期されたコンテキストの場合) を終了および再取得する場合は true 。それ以外の場合は false 。
戻り値
待機が成功した場合、またはタイムアウトしなかった場合は true 。それ以外の場合は false 。
例外
例外の種類 | 条件 |
---|---|
ArgumentNullException | obj パラメータが null 参照 (Visual Basic では Nothing) です。 |
SynchronizationLockException | Wait が、コードの同期ブロック内から呼び出されていません。 |
ThreadInterruptedException | Wait を呼び出したスレッドは、後で待機中の状態を中断されます。これは、別のスレッドがこのスレッドの Interrupt メソッドを呼び出すと発生します。 |
解説
このメソッドは、オブジェクトのモニタ待機ハンドルを取得します。このスレッドがオブジェクトのモニタ ロックを保持している場合は、ロックが解放されます。このメソッドが終了すると、スレッドはモニタ ロックを再取得します。
このオブジェクトのロックを現在保持しているスレッドは、このメソッドを呼び出して、オブジェクトの状態の条件が一致するまで待機します。 Wait を呼び出した直後に、 Wait を呼び出したスレッドはロックを解放し、待機キューに入ります。この時点で、実行待ちキュー内に次のスレッドが存在する場合は、そのスレッドがロックを制御できます。 Wait を呼び出したスレッドは、ロックを保持しているスレッドが PulseAll を呼び出すまで、または Wait を呼び出したスレッドがキュー内の次のスレッドの場合は、ロックを保持しているスレッドが Pulse を呼び出すまで、待機中のキュー内に残ります。ただし、他のスレッドがこのオブジェクトの Pulse メソッドまたは PulseAll メソッドを呼び出す前に millisecondsTimeout が経過すると、元のスレッドはロックを再取得するために実行待ちキューに移動します。オブジェクトの状態の条件が適合しなかった場合、スレッドは再び Wait を呼び出して、条件が合うまで待機中のキューを再入力します。
timeout が 0 の場合は、 Wait を呼び出すスレッドはロックを解放し、すぐに実行待ちキューに入ってロックを再取得します。
同期されたオブジェクトは、現在ロックを保持しているスレッドへの参照、ロックを取得する準備ができているスレッドを格納している実行待ちキューへの参照、オブジェクトの状態の変更通知を待機しているスレッドを格納している待機キューへの参照など、複数の参照を保持しています。 Pulse 、 PulseAll 、 Wait の各メソッドは、同期されたコードのブロック内から呼び出される必要があります。
使用例
[Visual Basic, C#, C++] Wait メソッドを使用する方法を次のコード例に示します。
Imports System
Imports System.Threading
Imports System.Collections
Namespace MonitorCS1
Class MonitorSample
Private MAX_LOOP_TIME As Integer = 1000
Private m_smplQueue As Queue
Public Sub New()
m_smplQueue = New Queue()
End Sub 'New
Public Sub FirstThread()
Dim counter As Integer = 0
SyncLock m_smplQueue
While counter < MAX_LOOP_TIME
'Wait, if the queue is busy.
Monitor.Wait(m_smplQueue)
'Push one element.
m_smplQueue.Enqueue(counter)
'Release the waiting thread.
Monitor.Pulse(m_smplQueue)
counter += 1
End While
End SyncLock
End Sub 'FirstThread
Public Sub SecondThread()
SyncLock m_smplQueue
'Release the waiting thread.
Monitor.Pulse(m_smplQueue)
'Wait in the loop while the queue is busy.
'Exit on the time-out when the first thread stops.
While Monitor.Wait(m_smplQueue, 1000)
'Pop the first element.
Dim counter As Integer = CInt(m_smplQueue.Dequeue())
'Print the first element.
Console.WriteLine(counter.ToString())
'Release the waiting thread.
Monitor.Pulse(m_smplQueue)
End While
End SyncLock
End Sub 'SecondThread
'Return the number of queue elements.
Public Function GetQueueCount() As Integer
Return m_smplQueue.Count
End Function 'GetQueueCount
Public Shared Sub Main(args() As String)
'Create the MonitorSample object.
Dim test As New MonitorSample()
'Create the first thread.
Dim tFirst As New Thread(AddressOf test.FirstThread)
'Create the second thread.
Dim tSecond As New Thread(AddressOf test.SecondThread)
'Start threads.
tFirst.Start()
tSecond.Start()
'wait to the end of the two threads
tFirst.Join()
tSecond.Join()
'Print the number of queue elements.
Console.WriteLine(("Queue Count = " + test.GetQueueCount().ToString()))
End Sub 'Main
End Class 'MonitorSample
End Namespace 'MonitorCS1
[C#]
using System;
using System.Threading;
using System.Collections;
namespace MonitorCS1
{
class MonitorSample
{
const int MAX_LOOP_TIME = 1000;
Queue m_smplQueue;
public MonitorSample()
{
m_smplQueue = new Queue();
}
public void FirstThread()
{
int counter = 0;
lock(m_smplQueue)
{
while(counter < MAX_LOOP_TIME)
{
//Wait, if the queue is busy.
Monitor.Wait(m_smplQueue);
//Push one element.
m_smplQueue.Enqueue(counter);
//Release the waiting thread.
Monitor.Pulse(m_smplQueue);
counter++;
}
}
}
public void SecondThread()
{
lock(m_smplQueue)
{
//Release the waiting thread.
Monitor.Pulse(m_smplQueue);
//Wait in the loop, while the queue is busy.
//Exit on the time-out when the first thread stops.
while(Monitor.Wait(m_smplQueue,1000))
{
//Pop the first element.
int counter = (int)m_smplQueue.Dequeue();
//Print the first element.
Console.WriteLine(counter.ToString());
//Release the waiting thread.
Monitor.Pulse(m_smplQueue);
}
}
}
//Return the number of queue elements.
public int GetQueueCount()
{
return m_smplQueue.Count;
}
static void Main(string[] args)
{
//Create the MonitorSample object.
MonitorSample test = new MonitorSample();
//Create the first thread.
Thread tFirst = new Thread(new ThreadStart(test.FirstThread));
//Create the second thread.
Thread tSecond = new Thread(new ThreadStart(test.SecondThread));
//Start threads.
tFirst.Start();
tSecond.Start();
//wait to the end of the two threads
tFirst.Join();
tSecond.Join();
//Print the number of queue elements.
Console.WriteLine("Queue Count = " + test.GetQueueCount().ToString());
}
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
using namespace System::Threading;
using namespace System::Collections;
__gc class MonitorSample
{
public:
MonitorSample();
void FirstThread();
void SecondThread();
int GetQueueCount();
private:
static const int MAX_LOOP_TIME = 1000;
Queue* m_smplQueue;
};
MonitorSample::MonitorSample()
{
m_smplQueue = new Queue();
}
void MonitorSample::FirstThread()
{
int counter = 0;
Monitor::Enter(m_smplQueue);
while(counter < MAX_LOOP_TIME)
{
//Wait, if the queue is busy.
Monitor::Wait(m_smplQueue);
//Push one element.
m_smplQueue->Enqueue(__box(counter));
//Release the waiting thread.
Monitor::Pulse(m_smplQueue);
counter++;
}
Monitor::Exit(m_smplQueue);
}
void MonitorSample::SecondThread()
{
Monitor::Enter(m_smplQueue);
//Release the waiting thread.
Monitor::Pulse(m_smplQueue);
//Wait in the loop, while the queue is busy.
//Exit on the time-out when the first thread stopped.
while(Monitor::Wait(m_smplQueue,1000))
{
//Pop the first element.
int counter = *dynamic_cast<__box int*>(m_smplQueue->Dequeue());
//Print the first element.
Console::WriteLine(counter.ToString());
//Release the waiting thread.
Monitor::Pulse(m_smplQueue);
}
Monitor::Exit(m_smplQueue);
}
//Return the number of queue elements.
int MonitorSample::GetQueueCount()
{
return m_smplQueue->Count;
}
int main()
{
//Create the MonitorSample object.
MonitorSample* test = new MonitorSample();
//Create the first thread.
Thread* tFirst = new Thread(new ThreadStart(test, &MonitorSample::FirstThread));
//Create the second thread.
Thread* tSecond = new Thread(new ThreadStart(test, &MonitorSample::SecondThread));
//Start threads.
tFirst->Start();
tSecond->Start();
//wait to the end of the two threads
tFirst->Join();
tSecond->Join();
//Print the number of queue elements.
Console::WriteLine(String::Concat(S"Queue Count = ", test->GetQueueCount().ToString()));
}
[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 ファミリ
参照
Monitor クラス | Monitor メンバ | System.Threading 名前空間 | Monitor.Wait オーバーロードの一覧 | Thread | スレッド処理 | Monitor