Freigeben über


Monitor.Pulse-Methode

Benachrichtigt einen Thread in der Warteschlange für abzuarbeitende Threads über eine Änderung am Zustand des gesperrten Objekts.

Namespace: System.Threading
Assembly: mscorlib (in mscorlib.dll)

Syntax

'Declaration
Public Shared Sub Pulse ( _
    obj As Object _
)
'Usage
Dim obj As Object

Monitor.Pulse(obj)
public static void Pulse (
    Object obj
)
public:
static void Pulse (
    Object^ obj
)
public static void Pulse (
    Object obj
)
public static function Pulse (
    obj : Object
)

Parameter

  • obj
    Das Objekt, auf das ein Thread wartet.

Ausnahmen

Ausnahmetyp Bedingung

ArgumentNullException

Der obj-Parameter ist NULL (Nothing in Visual Basic).

SynchronizationLockException

Der aufrufende Thread besitzt keine Sperre für das angegebene Objekt.

Hinweise

Nur der aktuelle Besitzer der Sperre kann mit Pulse ein wartendes Objekt signalisieren.

Der Thread, der gegenwärtig die Sperre für das angegebene Objekt besitzt, ruft diese Methode auf, um ein Signal an den nächsten für die Sperre anstehenden Thread zu senden. Nach dem Empfang des Impulses wird der wartenden Thread in die Warteschlange für abgearbeitete Threads verschoben. Wenn der Thread, der Pulse aufgerufen hat, die Sperre aufhebt, erhält der nächste Thread in der Warteschlange für abgearbeitete Threads die Sperre (dies ist nicht unbedingt der Thread, der den Impuls empfangen hat).

Wichtig

Die Monitor-Klasse verwaltet nicht den Zustand, der angibt, dass die Pulse-Methode aufgerufen wurde. Daher wird, wenn Sie Pulse aufrufen und keine Threads warten, der nächste Thread, der Wait aufruft, gesperrt. Dies entspricht dem Verhalten, wenn Pulse nicht aufgerufen wird. Wenn zwei Threads Pulse und Wait für die Interaktion verwenden, könnte dies zu einem Deadlock führen. Vergleichen Sie dies mit dem Verhalten der AutoResetEvent-Klasse: Wenn Sie ein AutoResetEvent durch Aufruf seiner Set-Methode signalisieren und keine Threads warten, verbleibt das AutoResetEvent in einem Signalzustand, bis ein Thread WaitOne, WaitAny oder WaitAll aufruft. Das AutoResetEvent gibt den Thread frei und beendet den Signalzustand.

Beachten Sie, dass ein synchronisiertes Objekt mehrere Verweise enthält, darunter ein Verweis auf den Thread, der gegenwärtig die Sperre besitzt, ein Verweis auf die Warteschlange mit den abgearbeiteten Threads, die die Sperre erhalten können, und ein Verweis auf die Warteschlange mit den abzuarbeitenden Threads, die auf die Benachrichtigung über eine Änderung des Objektzustands warten.

Die Pulse-Methode, die PulseAll-Methode und die Wait-Methode müssen aus einem synchronisierten Codeblock heraus aufgerufen werden.

Verwenden Sie die PulseAll-Methode, um Signale an mehrere Threads zu senden.

Beispiel

Das folgende Codebeispiel veranschaulicht die Verwendung der Pulse-Methode.

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 
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());
        }
    }
}
using namespace System;
using namespace System::Threading;
using namespace System::Collections;
ref class MonitorSample
{
public:
   MonitorSample();
   void FirstThread();
   void SecondThread();
   int GetQueueCount();

private:
   literal int MAX_LOOP_TIME = 1000;
   Queue^ m_smplQueue;
};

MonitorSample::MonitorSample()
{
   m_smplQueue = gcnew 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( 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<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 = gcnew MonitorSample;
   
   //Create the first thread.
   Thread^ tFirst = gcnew Thread( gcnew ThreadStart( test, &MonitorSample::FirstThread ) );
   
   //Create the second thread.
   Thread^ tSecond = gcnew Thread( gcnew 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( "Queue Count = ", test->GetQueueCount().ToString() ) );
}
package MonitorJSL1;

import System.*;
import System.Threading.*;
import System.Collections.*;

class MonitorSample
{
    private int MAX_LOOP_TIME = 1000;
    private Queue mSmplQueue;

    public MonitorSample()
    {
        mSmplQueue = new Queue();
    } //MonitorSample

    public void FirstThread()
    {
        int counter = 0;
        synchronized (mSmplQueue) {
            while (counter < MAX_LOOP_TIME) {
                //Wait, if the queue is busy.
                Monitor.Wait(mSmplQueue);

                //Push one element.
                mSmplQueue.Enqueue((Int32)counter);

                //Release the waiting thread.
                Monitor.Pulse(mSmplQueue);
                counter++;
            }
        }
    } //FirstThread

    public void SecondThread()
    {
        synchronized (mSmplQueue) {
            //Release the waiting thread.
            Monitor.Pulse(mSmplQueue);

            //Wait in the loop, while the queue is busy.
            //Exit on the time-out when the first thread stops. 
            while (Monitor.Wait(mSmplQueue, 1000)) {
                //Pop the first element.
                int counter = Convert.ToInt32(mSmplQueue.Dequeue());

                //Print the first element.
                Console.WriteLine(Convert.ToString(counter));

                //Release the waiting thread.
                Monitor.Pulse(mSmplQueue);
            }
        }
    } //SecondThread

    //Return the number of queue elements.
    public int GetQueueCount()
    {
        return mSmplQueue.get_Count();
    } //GetQueueCount

    public static void main(String[] args)
    {
        //Create the MonitorSample object.
        MonitorSample test = new MonitorSample();

        //Create the first thread.
        System.Threading.Thread tFirst = 
            new System.Threading.Thread(new ThreadStart(test.FirstThread));

        //Create the second thread.
        System.Threading.Thread tSecond = 
            new System.Threading.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 = "
            + Convert.ToString(test.GetQueueCount()));
    } //main
} //MonitorSample

Plattformen

Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

.NET Framework unterstützt nicht alle Versionen sämtlicher Plattformen. Eine Liste der unterstützten Versionen finden Sie unter Systemanforderungen.

Versionsinformationen

.NET Framework

Unterstützt in: 2.0, 1.1, 1.0

Siehe auch

Referenz

Monitor-Klasse
Monitor-Member
System.Threading-Namespace
Thread

Weitere Ressourcen

Verwaltetes Threading
Monitore