views:

49

answers:

2

Dear All

I would like to ask couple of Questions regarding the use of Monitor Class in .Net.

To understand the Questions please look at the following Code.

public class MyClass
{
    private List<int> _MyCollection = new List<int>();

    public void GetLock()
    {
        Monitor.Enter(_MyCollection);
    }

    public void ReleaseLock()
    {
        Monitor.Exit(_MyCollection);
    }

    public void UpdateCollection(/*anyparam*/)
    {
        //update collection without lock on collection
    }
}

public class MyAppMain
{
    private static MyClass myclass = new MyClass();

    public static void main(args)
    {
        try
        {
            myclass.GetLock();

            //an operation that does not do any update on myclass but wanted 
            //to ensure that the collection within myclass never update
            //while its doing following opetion

            //Do somthing
        }
        finally
        {
            myclass.ReleaseLock();
        }
    }
}

Now is this the right use of monitor and do i need to use Pulse or PulseAll to signal waiting thread and if so than should use plus before or after Exit function?

Regards Mubashar

+2  A: 

Obtaining your lock and then releasing it in a finally block is correct. I'd get the lock before the try block starts but it probably won't hurt anything unless an exception gets thrown by the attempt to obtain the lock.

For what you are actually trying to do, you are going to need to rethink what your goal is. Depending on whether or not performance is a concern, you might look into the ReaderWriterLock. If contention is low, consider locking every operation but using a spin lock - which is extremely cheap for operations that do not tend to overlap but might.

Also: I think you need to revisit the notion of updating the collection without locking unless you can ensure that only one thread will be updating the collection.

1. you are right about the obtaining the lock before Try i normally do the same as you suggested. 2. You are again right regarding the use of ReaderWriterLockSlim i am considering it since i added this post ;). Actually the above code is not exactly what i am trying to do but just a brief reflection of that. 3. Sorry for my bad read skills i am unable to understand what you said followed by "Also:"
Mubashar Ahmad
3. Simple. I don't know what your level of threading experience is. I think that, if you do not have a *very* strong threading background, the comment `//update collection without lock on collection` in your sample code implies you are heading down a very dangerous path unless there is something about the context of how your class will be used that you have not told us.
Ooops actually i forgot to add UpdateCollection function call after //do something as the locks are already taken by by the caller using GetLock function.
Mubashar Ahmad
Ok you havn't mention anything about Pulse/PluseAll function is it mandatory to call after Exit function while using Monitor???
Mubashar Ahmad
No. Pulse/PulseAll has to be called _before_ Exit() and it only needs to be called if other threads have called Wait().
+2  A: 

Yes, your usage of Monitor is correct.

That said, you can use the lock statement to make the code more concise:

public static void main(args)
{
    lock(myclass)
    {
    }
}
R Samuel Klatchko
Actually if you replace the my List<int> to List<List<int>> and Get Lock and Release locks work only on specific List<int> within the main List. then lock statement will be not be applicable. In short i don't want to lock the whole collection object but a part within that collection by using GetLock and Release Lock functions.
Mubashar Ahmad
@MubasharAhmad - the `lock` statement can use any object that `Monitor.Enter` can use. So you could add a function to MyClass `public Object GetLockTarget() { return ...; }` and then lock it by doing `lock(myclass.GetLockTarget())`
R Samuel Klatchko
hmm thats what i never thought of :D. thanks
Mubashar Ahmad