This documentation is archived and is not being maintained.

Monitor.Exit Method

Releases an exclusive lock on the specified object.

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

Parameters

obj
The object on which to release the lock.

Exceptions

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

Remarks

The caller must own the lock on the obj parameter. If the caller owns the lock on the specified object, and has made an equal number of Exit and Enter calls for the object, then the lock is released. If the caller has not invoked Exit as many times as Enter, the lock is not released.

If the lock is released and other threads are in the ready queue for the object, one of the threads acquires the lock. If other threads are in the waiting queue waiting to acquire the lock, they are not automatically moved to the ready queue when the owner of the lock calls Exit. To move one or more waiting threads into the ready queue, call Pulse or PulseAll before invoking Exit.

Example

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

[Visual Basic] 
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

[C#] 
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();

        }
    }
}

[C++] 
#using <mscorlib.dll>

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

// Class definition
public __gc 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 = new 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;
    }
    //Unlock the queue.
    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());
    }
    //Unlock the queue.
    Monitor::Exit(m_inputQueue);   
}

int main() {
    MonitorSample* sample = new MonitorSample();

    for(int i = 0; i < 30; i++)
        sample->AddElement(__box(i));
    sample->PrintAllElements();
    sample->DeleteElement(__box(0));
    sample->DeleteElement(__box(10));
    sample->DeleteElement(__box(20));
    sample->PrintAllElements();
}

[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, .NET Compact Framework, Common Language Infrastructure (CLI) Standard

See Also

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

Show: