Export (0) Print
Expand All

Monitor.Enter Method

Acquires an exclusive lock on the specified object.

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

public static void Enter (
	Object obj
)
public static void Enter (
	Object obj
)
public static function Enter (
	obj : Object
)

Parameters

obj

The object on which to acquire the monitor lock.

Exception typeCondition

ArgumentNullException

The obj parameter is a null reference (Nothing in Visual Basic).

Use Enter to acquire the Monitor on the object passed as the parameter. If another thread has executed an Enter on the object, but has not yet executed the corresponding Exit, the current thread will block until the other thread releases the object. It is legal for the same thread to invoke Enter more than once without it blocking; however, an equal number of Exit calls must be invoked before other threads waiting on the object will unblock.

Use Monitor to lock objects (that is, reference types), not value types. When you pass a value type variable to Enter, it is boxed as an object. If you pass the same variable to Enter again, it is boxed as a separate object, and the thread does not block. The code that Monitor is supposedly protecting is not protected. Furthermore, when you pass the variable to Exit, still another separate object is created. Because the object passed to Exit is different from the object passed to Enter, Monitor throws SynchronizationLockException. For details, see the conceptual topic Monitors.

Interrupt can interrupt threads waiting to enter a Monitor on an object. A ThreadInterruptedException will be thrown.

Use a C# tryfinally block (TryFinally in Visual Basic) to ensure that you release the monitor, or use the C# lock statement (SyncLock in Visual Basic), which wraps the Exit method in a tryfinally block.

The following example demonstrates how to use the Enter method.

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();

		}
	}
}


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

Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see System Requirements.

.NET Framework

Supported in: 2.0, 1.1, 1.0

.NET Compact Framework

Supported in: 2.0, 1.0

Community Additions

ADD
Show:
© 2014 Microsoft