Export (0) Print
Expand All

Monitor.Pulse Method

Notifies a thread in the waiting queue of a change in the locked object's state.

[Visual Basic]
Public Shared Sub Pulse( _
   ByVal obj As Object _
)
[C#]
public static void Pulse(
 object obj
);
[C++]
public: static void Pulse(
 Object* obj
);
[JScript]
public static function Pulse(
   obj : Object
);

Parameters

obj
The object a thread is waiting for.

Exceptions

Exception Type Condition
ArgumentNullException The obj parameter is a null reference (Nothing in Visual Basic).
SynchronizationLockException The calling thread does not own the lock for the specified object.

Remarks

Only the current owner of the lock can signal a waiting object using Pulse.

The thread that currently owns the lock on the specified object invokes this method to signal the next thread in line for the lock. Upon receiving the pulse, the waiting thread is moved to the ready queue. When the thread that invoked Pulse releases the lock, the next thread in the ready queue (which is not necessarily the thread that was pulsed) acquires the lock.

Note that a synchronized object holds several references, including a reference to the thread that currently holds the lock, a reference to the ready queue, which contains the threads that are ready to obtain the lock, and a reference to the waiting queue, which contains the threads that are waiting for notification of a change in the object's state. The Pulse, PulseAll, and Wait methods must be invoked from within a synchronized block of code. The remarks for Wait(Object, Int32) address an issue that arises when Pulse is invoked before Wait.

To signal multiple threads, use the PulseAll method.

Example

[Visual Basic, C#, C++] The following code example demonstrates how to use the Pulse method.

[Visual Basic] 
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] No example is available for JScript. To view a Visual Basic, C#, or C++ example, click the Language Filter button Language Filter in the upper-left corner of the page.

Requirements

Platforms: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 family, Common Language Infrastructure (CLI) Standard

See Also

Monitor Class | Monitor Members | System.Threading Namespace | Thread | Threading | Monitor

Show:
© 2014 Microsoft