tags:

views:

128

answers:

4

when using a lock does the thing you are locking on have to be a object. For example is this legal

    static DateTime NextCleanup = DateTime.Now;
    const TimeSpan CleanupInterval = new TimeSpan(1, 0, 0);
    private static void DoCleanup()
    {
        lock ((object)NextCleanup)
        {
            if (NextCleanup < DateTime.Now)
            {
                NextCleanup = DateTime.Now.Add(CleanupInterval);
                System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(cleanupThread));
            }
        }
        return;
    }
+10  A: 

You can lock on any reference type.

Since DateTime is not a reference type, you cannot lock on it.
If you try, each call to Monitor.Enter will receive a different boxed DateTime value, and the lock will be effectively useless.

What are you trying to do?
As far as the runtime is concerned, it doesn't matter at all which object you lock on. (Locking on an object will not magically prevent other threads from using the object unless they explicitly lock on the same object)
When you lock on an object, you should choose an object that all of the necessary pieces of code will lock on.

See also CA2002.

SLaks
It should be noted that all reference types are objects, so there will be no need to cast. Also, make sure the variable you use lock always refers to the same object.
Eric Mickelsen
great answer -- I will have to keep this in mind for future reference!
Dave
What I am trying to do is just prevent another thread from checking to see if the hour has passed before it can be updated.
Scott Chamberlain
A: 

It doesn't have to be of type System.Object, but is there a reason to not use an object?

John Saunders
Read my update. I meant `System.Object`.
John Saunders
I think what John is saying is that it doesn't have to be cast to System.Object like the OP entered. Or he might have meant that you don't have to create a System.Object member and then use *that* as the lock. I only say this because as a newbie, I used to create a System.Object solely for locking, when I could have used pretty much anything since everything is derived from System.Object.
Dave
@SLaks: It has to be a reference type. I think John means it doesn't have to be a bare minimum `System.Object` but can be any reference type that derives from it.
Dan Tao
+6  A: 

Be aware that even if what you are trying to do here were possible (i.e., if DateTime were a reference type and therefore something you could lock on), it wouldn't be legal because you're setting NextCleanup to a new value within the lock block.

You cannot set a reference to a new object within a block of code which has locked on that object.

This is why it's advisable to have a dedicated "lock" object to use for all code that needs to be synchronized for a related purpose.

Dan Tao
This is the first good explanation to why you should use a separate object for locking than the object you plan on using.
Scott Chamberlain
+1  A: 

It looks like what you are trying to do is run a cleanup routine periodically. If that is the case, you can use System.Threading.Timer, which is specifically designed for running periodic tasks.

Mark Nelson