Freigeben über


Monitor.Enter-Methode

Erhält eine exklusive Sperre für das angegebene Objekt.

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

Syntax

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

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

Parameter

  • obj
    Das Objekt, für das die Monitorsperre erhalten werden soll.

Ausnahmen

Ausnahmetyp Bedingung

ArgumentNullException

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

Hinweise

Mit Enter können Sie den Monitor für das als Parameter übergebene Objekt abrufen. Wenn ein anderer Thread zwar Enter für das Objekt, jedoch noch nicht das entsprechende Exit ausgeführt hat, wird der aktuelle Thread blockiert, bis der andere Thread das Objekt freigibt. Derselbe Thread kann Enter mehrmals ausführen, ohne dass er blockiert wird. Exit muss jedoch ebenso so oft aufgerufen werden, bevor die Blockierung anderer Threads aufgehoben wird, die auf das Objekt warten.

Mit Monitor können Sie Objekte (d. h. Verweistypen), aber keine Werttypen sperren. Wenn Sie eine Werttypvariable an Enter übergeben, wird sie als Objekt geschachtelt. Wenn Sie dieselbe Variable wieder an Enter übergeben, wird sie als separates Objekt geschachtelt und der Thread wird nicht blockiert. Der von Monitor zu schützende Code ist nicht geschützt. Außerdem wird beim Übergeben der Variablen an Exit ein weiteres Objekt erstellt. Da das an Exit übergebene Objekt sich von dem an Enter übergebenen Objekt unterscheidet, löst Monitor eine SynchronizationLockException aus. Ausführliche Informationen finden Sie unter dem Thema Monitore.

Interrupt kann Threads unterbrechen, die auf die Aufnahme in einen Monitor für ein Objekt warten. Eine ThreadInterruptedException wird ausgelöst.

Stellen Sie mit einem tryfinally-Block in C# (TryFinally in Visual Basic) sicher, dass der Monitor freigegeben wird, oder verwenden Sie die lock-Anweisung in C# (SyncLock in Visual Basic), die die Exit-Methode in einen tryfinally-Block einschließt.

Beispiel

Das folgende Beispiel veranschaulicht die Verwendung der Enter-Methode.

Imports System
Imports System.Threading
Imports System.Collections


Class MonitorSample
    'Define the queue to safe thread access.
    Private m_inputQueue As Queue

    Public Sub New()
        m_inputQueue = New Queue()
    End Sub

    'Add an element to the queue and obtain the monitor lock for the queue object.
    Public Sub AddElement(ByVal qValue As Object)
        'Lock the queue.
        Monitor.Enter(m_inputQueue)
        'Add an element.
        m_inputQueue.Enqueue(qValue)
        'Unlock the queue.
        Monitor.Exit(m_inputQueue)
    End Sub

    'Try to add an element to the queue.
    'Add the element to the queue only if the queue object is unlocked.
    Public Function AddElementWithoutWait(ByVal qValue As Object) As Boolean
        'Determine whether the queue is locked.
        If Not Monitor.TryEnter(m_inputQueue) Then
            Return False
        Else
            m_inputQueue.Enqueue(qValue)
            Monitor.Exit(m_inputQueue)
            Return True
        End If
    End Function

    'Try to add an element to the queue. 
    'Add the element to the queue only if during the specified time the queue object will be unlocked.
    Public Function WaitToAddElement(ByVal qValue As Object, ByVal waitTime As Integer) As Boolean
        'Wait while the queue is locked.
        If Not Monitor.TryEnter(m_inputQueue, waitTime) Then
            Return False
        Else
            m_inputQueue.Enqueue(qValue)
            Monitor.Exit(m_inputQueue)
            Return True
        End If
    End Function

    'Delete all elements that equal the given object and obtain the monitor lock for the queue object.
    Public Sub DeleteElement(ByVal qValue As Object)
        'Lock the queue.
        Monitor.Enter(m_inputQueue)
        Dim counter As Integer = m_inputQueue.Count
        While (counter > 0)  
            'Check each element.
            Dim elm As Object = m_inputQueue.Dequeue()
            If Not elm.Equals(qValue) Then
                m_inputQueue.Enqueue(elm)
            End If
            counter = counter - 1
        End While
        'Unlock the queue.
        Monitor.Exit(m_inputQueue)
    End Sub

    'Print all queue elements.
    Public Sub PrintAllElements()
        'Lock the queue.
        Monitor.Enter(m_inputQueue)
        Dim elmEnum As IEnumerator = m_inputQueue.GetEnumerator()
        While elmEnum.MoveNext()
            'Print the next element.
            Console.WriteLine(elmEnum.Current.ToString())
        End While
        'Unlock the queue.
        Monitor.Exit(m_inputQueue)
    End Sub

    Public Shared Sub Main()
        Dim sample As MonitorSample = New MonitorSample()
        Dim i As Integer

        For i = 0 To 29
            sample.AddElement(i)
        Next i
        sample.PrintAllElements()
        sample.DeleteElement(0)
        sample.DeleteElement(10)
        sample.DeleteElement(20)
        sample.PrintAllElements()
    End Sub

End Class
using System;
using System.Collections;
using System.Threading;

namespace MonitorCS2
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class MonitorSample
    {
        //Define the queue to safe thread access.
        private Queue m_inputQueue;

        public MonitorSample()
        {
            m_inputQueue = new Queue(); 
        }

        //Add an element to the queue and obtain the monitor lock for the queue object.
        public void AddElement(object qValue)
        {
            //Lock the queue.
            Monitor.Enter(m_inputQueue);
            //Add element
            m_inputQueue.Enqueue(qValue);
            //Unlock the queue.
            Monitor.Exit(m_inputQueue);
        }

        //Try to add an element to the queue.
        //Add the element to the queue only if the queue object is unlocked.
        public bool AddElementWithoutWait(object qValue)
        {
            //Determine whether the queue is locked 
            if(!Monitor.TryEnter(m_inputQueue))
                return false;
            m_inputQueue.Enqueue(qValue);

            Monitor.Exit(m_inputQueue);
            return true;
        }

        //Try to add an element to the queue. 
        //Add the element to the queue only if during the specified time the queue object will be unlocked.
        public bool WaitToAddElement(object qValue, int waitTime)
        {
            //Wait while the queue is locked.
            if(!Monitor.TryEnter(m_inputQueue,waitTime))
                return false;
            m_inputQueue.Enqueue(qValue);
            Monitor.Exit(m_inputQueue);

            return true;
        }
        
        //Delete all elements that equal the given object and obtain the monitor lock for the queue object.
        public void DeleteElement(object qValue)
        {
            //Lock the queue.
            Monitor.Enter(m_inputQueue);
            int counter = m_inputQueue.Count;
            while(counter > 0)
            {   
                //Check each element.
                object elm = m_inputQueue.Dequeue();
                if(!elm.Equals(qValue))
                {
                    m_inputQueue.Enqueue(elm);
                }
                --counter;
            }
            //Unlock the queue.
            Monitor.Exit(m_inputQueue);
        }
        
        //Print all queue elements.
        public void PrintAllElements()
        {
            //Lock the queue.
            Monitor.Enter(m_inputQueue);            
            IEnumerator elmEnum = m_inputQueue.GetEnumerator();
            while(elmEnum.MoveNext())
            {
                //Print the next element.
                Console.WriteLine(elmEnum.Current.ToString());
            }
            //Unlock the queue.
            Monitor.Exit(m_inputQueue); 
        }

        static void Main(string[] args)
        {
            MonitorSample sample = new MonitorSample();
            
            for(int i = 0; i < 30; i++)
                sample.AddElement(i);
            sample.PrintAllElements();
            sample.DeleteElement(0);
            sample.DeleteElement(10);
            sample.DeleteElement(20);
            sample.PrintAllElements();

        }
    }
}
using namespace System;
using namespace System::Collections;
using namespace System::Threading;

// Class definition
public ref class MonitorSample
{
public:
   MonitorSample();
   void AddElement( Object^ qValue );
   bool AddElementWithoutWait( Object^ qValue );
   bool WaitToAddElement( Object^ qValue, int waitTime );
   void DeleteElement( Object^ qValue );
   void PrintAllElements();

private:
   Queue^ m_inputQueue;
};


//Define the queue to safe thread access.
MonitorSample::MonitorSample()
{
   m_inputQueue = gcnew Queue;
}


//Add an element to the queue and obtain the monitor lock for the queue object.
void MonitorSample::AddElement( Object^ qValue )
{
   
   //Lock the queue.
   Monitor::Enter( m_inputQueue );
   
   //Add element
   m_inputQueue->Enqueue( qValue );
   
   //Unlock the queue.
   Monitor::Exit( m_inputQueue );
}


//Try to add an element to the queue.
//Add the element to the queue only if the queue object is unlocked.
bool MonitorSample::AddElementWithoutWait( Object^ qValue )
{
   
   //Determine whether the queue is locked 
   if (  !Monitor::TryEnter( m_inputQueue ) )
      return false;

   m_inputQueue->Enqueue( qValue );
   Monitor::Exit( m_inputQueue );
   return true;
}


//Try to add an element to the queue. 
//Add the element to the queue only if during the specified time the queue object will be unlocked.
bool MonitorSample::WaitToAddElement( Object^ qValue, int waitTime )
{
   
   //Wait while the queue is locked.
   if (  !Monitor::TryEnter( m_inputQueue, waitTime ) )
      return false;

   m_inputQueue->Enqueue( qValue );
   Monitor::Exit( m_inputQueue );
   return true;
}


//Delete all elements that equal the given object and obtain the monitor lock for the queue object.
void MonitorSample::DeleteElement( Object^ qValue )
{
   
   //Lock the queue.
   Monitor::Enter( m_inputQueue );
   int counter = m_inputQueue->Count;
   while ( counter > 0 )
   {
      
      //Check each element.
      Object^ elm = m_inputQueue->Dequeue();
      if (  !elm->Equals( qValue ) )
      {
         m_inputQueue->Enqueue( elm );
      }

      --counter;
   }

   Monitor::Exit( m_inputQueue );
}


//Print all queue elements.
void MonitorSample::PrintAllElements()
{
   
   //Lock the queue.
   Monitor::Enter( m_inputQueue );
   IEnumerator^ elmEnum = m_inputQueue->GetEnumerator();
   while ( elmEnum->MoveNext() )
   {
      
      //Print the next element.
      Console::WriteLine( elmEnum->Current->ToString() );
   }

   Monitor::Exit( m_inputQueue );
}

int main()
{
   MonitorSample^ sample = gcnew MonitorSample;
   for ( int i = 0; i < 30; i++ )
      sample->AddElement( i );
   sample->PrintAllElements();
   sample->DeleteElement( 0 );
   sample->DeleteElement( 10 );
   sample->DeleteElement( 20 );
   sample->PrintAllElements();
}
package MonitorJSL2;

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

/// <summary>
/// Summary description for Class1.
/// </summary>
    
class MonitorSample
{
    //Define the queue to safe thread access.
    private Queue mInputQueue;

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

    // Add an element to the queue and obtain the monitor lock for the 
    // queue object.
    public void AddElement(Object qValue)
    {
        //Lock the queue.
        Monitor.Enter(mInputQueue);

        //Add element
        mInputQueue.Enqueue(qValue);

        //Unlock the queue.
        Monitor.Exit(mInputQueue);
    } //AddElement

    //Try to add an element to the queue.
    //Add the element to the queue only if the queue object is unlocked.
    public boolean AddElementWithoutWait(Object qValue)
    {
        //Determine whether the queue is locked 
        if (!(Monitor.TryEnter(mInputQueue))) {
            return false;
        }
        mInputQueue.Enqueue(qValue);
        Monitor.Exit(mInputQueue);
        return true;
    } //AddElementWithoutWait

    //Try to add an element to the queue. 
    //Add the element to the queue only if during the specified time the 
    //queue object will be unlocked.
    public boolean WaitToAddElement(Object qValue, int waitTime)
    {
        //Wait while the queue is locked.
        if (!(Monitor.TryEnter(mInputQueue, waitTime))) {
            return false;
        }
        mInputQueue.Enqueue(qValue);
        Monitor.Exit(mInputQueue);

        return true;
    } //WaitToAddElement

    //Delete all elements that equal the given object and obtain the 
    //monitor lock for the queue object.
    public void DeleteElement(Object qValue)
    {
        //Lock the queue.
        Monitor.Enter(mInputQueue);
        int counter = mInputQueue.get_Count();
        while (counter > 0) {
            //Check each element.
            Object elm = mInputQueue.Dequeue();
            if (!(elm.Equals(qValue))) {
                mInputQueue.Enqueue(elm);
            }
            --counter;
        }

        //Unlock the queue.
        Monitor.Exit(mInputQueue);
    } //DeleteElement

    //Print all queue elements.
    public void PrintAllElements()
    {
        //Lock the queue.
        Monitor.Enter(mInputQueue);
        IEnumerator elmEnum = mInputQueue.GetEnumerator();
        while (elmEnum.MoveNext()) {
            //Print the next element.
            Console.WriteLine(elmEnum.get_Current().ToString());
        }

        //Unlock the queue.
        Monitor.Exit(mInputQueue);
    } //PrintAllElements

    public static void main(String[] args)
    {
        MonitorSample sample = new MonitorSample();

        for (int i = 0; i < 30; i++) {
            sample.AddElement((Int32)i);
        }
        sample.PrintAllElements();
        sample.DeleteElement((Int32)0);
        sample.DeleteElement((Int32)10);
        sample.DeleteElement((Int32)20);
        sample.PrintAllElements();
    } //main 
} //MonitorSample

Plattformen

Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile für Pocket PC, Windows Mobile für Smartphone, 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

.NET Compact Framework

Unterstützt in: 2.0, 1.0

Siehe auch

Referenz

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

Weitere Ressourcen

Verwaltetes Threading
Monitore