I'm wondering if this construction will cause an error:
lock(sync)
{
// something
lock(sync)
{
//something
lock(sync)
{
//something
}
}
}
I've run this code, and it seems fine, but maybe in some circumstances an error may be thrown?
lock is a wrapper for Monitor.Enter and Monitor.Exit:
The lock keyword calls Enter at the start of the block and Exit at the end of the block. From the former's documentation:
From the documentation for Monitor.Enter:
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.
Because the calls to Enter and Exit are paired, your code pattern has well defined behaviour.
Note, however, that lock is not guaranteed to be an exception-less construct:
A ThreadInterruptedException is thrown if Interrupt interrupts a thread that is waiting to enter a lock statement.
To explain why it is well-defined behavior and will never fail:
Aside: This answer has better details about how locks actually work
The lock occurs at the Thread level, so calling it a second time on the same thread will be redundant. I would think it would not have any performance penalty (although that would depend on how exactly the internals of .Net are written, so I can't guarantee that)
Many times you'd have a public function that calls another public function in your class, whom both need the lock when used seperately. If this was not allowed the following would fail:
private Dictionary<string, int> database = new Dictionary<string, int>();
private object databaseLock = new object();
public void AddOrUpdate(string item)
{
lock (databaseLock)
{
if (Exists(item))
database.Add(item, 1);
else
++database[item];
}
}
public bool Exists(string item)
{
lock (databaseLock)
{
//... Maybe some pre-processing of the key or item...
return database.ContainsKey(item);
}
}
According to MSDN (see here and here) this is well-defined behaviour and causes no problem.
Related
I came across this definition of Object constructor (metadata from mscorlib.dll)
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public Object();
I didn't understood what ConstrainedExecution (Cer.MayFail) mean can someone tell me with an example in this case.
I came across this code, also tell me if it is correct to write like this,
public class MyClass
{
private static object instanceLock = new object();
private void Func()
{
bool instanceLockTaken = false;
Monitor.TryEnter(instanceLock, ref instanceLockTaken);
//...
Monitor.Exit(instanceLock);
}
}
Constrained Execution is what you're trying to achieve by locking the thread.
From: http://msdn.microsoft.com/en-us/magazine/cc163716.aspx
A Cer value of MayFail is used to signal that when faced with
asynchronous exceptions, the code may not complete in an expected
fashion. Since thread aborts are being delayed over constrained
execution regions, this really means that your code is doing something
that may cause memory to be allocated or that might result in a stack
overflow. More importantly, it means that you must take the possible
failures into consideration when calling this method.
In your case, because the object is static and only created once, this will not be a problem.
Monitor.TryEnter returns immediately even if a lock was not acquired. It has a boolean value, which you're not checking, something like this would work:
Monitor.TryEnter(instanceLock, ref instanceLockTaken);
if (instanceLockTaken)
{
// Do stuff here
Monitor.Exit(instanceLock);
}
However, this code would mean that the if {} block would not be executed every time, if you want to acquire a lock on every thread, you'll need to do something like this:
lock(instanceLock)
{
// Do stuff here
}
This means that only a single thread can run the contents of the lock {} statement at a time, and the contents of the lock statement will be executed every time.
On a side note, you can also make the object you're locking readonly:
private static readonly object instanceLock = new object();
So, generally speaking, you have 2 questions here.
1) Reliability contracts is a tool used by CLR team to support constrained execution regions. It is an advanced topic, but simply speaking the construction describes if a function (or a constructor) can fail, and if yes, what impact will be ( no impact, appDomain impact, process impact, whole machine crush, etc)
2) Your code snippet is incorrect. Why do you saving instanceLockTaken if you are not going to check it further? Furthermore, if exception occur between the lock acquisition and releasing it, you'll leak the lock.
Consider using the lock statement, which is syntax sugar for something like this:
bool instanceLockTaken = false;
try
{
Monitor.Enter(instanceLock, ref instanceLockTaken);
//...
}
finally
{
if (instanceLockTaken)
{
Monitor.Exit(instanceLock);
}
}
Cer.Mayfail keyword implies that if the marked method throws an exception, the data may be in an invalid state; the previous state of the object will not be restored.
This is the correct way for Monitor locking;
bool isLocked = false;
try
{
Monitor.Enter(instanceLock , ref isLocked);
// Do some things within the lock
}
finally
{
if (isLocked) Monitor.Exit(instanceLock);
}
As for cer.mayfail this link will provide some more information http://weblogs.asp.net/justin_rogers/archive/2004/10/05/238275.aspx
If I have something like this:
private readonly object objectLock = new object();
public void MethodA()
{
lock(objectLock)
{
//do something
}
}
public void MethodB()
{
lock(objectLock)
{
//do something
}
}
If I have 2 threads and both come in at the same time, 1st thread calls MethodA and second Method B. Whichever gets there first and locks objectLock, I assume the other thread sits there waiting until objectLock is no longer locked.
Yes, your explanation is right -- unless the lock is already taken (in which case both threads sit waiting, and an arbitrary one gets the lock as soon as it's unlocked).
(Slightly offtopic) I would advise not to lock the whole methods if they are doing something non-trivial. Try to keep the "locking" section of code as small and as fast as possible.
That is correct.
However it is not the objectLock that is locked (nor the object) it is the code blocks that are locked.
Think of the object that is passed to the lock keyword as a key that does unlock multiple doors but only grants access to a single room at one time.
You're absolutely right! But be careful with locks. Locks will maybe make you're program thread-safe (means, no errors on concurrent accesses) but it takes much more effort making make your program taking real advantage from running on a multi-kernel system.
yes you are right as Monitor.Enter and Monitor.Exit is called on same object objectLock behind the scene. remember its the code block that is synchronized not the objectLock.
You're correct. If this isn't desirable, then consider that:
lock(objectLock)
{
//do something
}
Is equivalent to:
Monitor.Enter(objectLock);
try
{
//do something
}
finally
{
Monitor.Exit(objectLock);
}
You can replace this with:
if(Monitor.TryEnter(objectLock, 250))//Don't wait more than 250ms
{
try
{
//do something
}
finally
{
Monitor.Exit(objectLock);
}
}
else
{
//fallback code
}
It's also worth looking at the overloads of TryEnter(), and the other synchronisation objects such as ReaderWriterLockSlim.
I need to use lock object, but it is already used by another thread. I wish to wait while the lock object will be free but have no idea how to do this.
I found sth like:
if(Monitor.TryEnter(_lock)
{
try
{
// do work
}
finally
{
Monitor.Exit(_lock);
}
}
But I it just check and go on, but I wish to wait until lock object is free.
Either use this:
Monitor.Enter(_lock)
try
{
// do work
}
finally
{
Monitor.Exit(_lock);
}
or - more preferably - the lock keyword:
lock(_lock)
{
// do work
}
In fact, those code snippets will generate the same code. The compiler will translate the second code into the first one. However, the second one is preferred because it is far more readable.
UPDATE:
The lock belongs to the thread it was acquired in. That means, nested usage of the lock statement is possible:
void MethodA()
{
lock(_lock)
{
// ...
MethodB();
}
}
void MethodB()
{
lock(_lock)
{
// ...
}
}
The above code will not block.
You can use Monitor.Enter
From docs:
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.
I agree with #Daniel Hilgarth, the lock syntax is preferred.
Regarding your question:
I wish to wait while the lock object will be free but have no idea how to do this.
As per the MSDN description:
lock ensures that one thread does not enter a critical section while another thread is in the critical section of code. If another thread attempts to enter a locked code, it will wait (block) until the object is released.
i.e. the code you have already does what you want it to.
In the piece of code that I'm working on, another developer's library fires off one of my object's methods on regular, scheduled intervals. I've run into problems where the previous call into my object's method has not completed at the time another interval is reached and a second call is made into my method to execute again - the two threads then end up stepping on each other. I'd like to be able to wrap the method's implementation with a check to see whether it is in the middle of processing and skip over the block if so.
A lock is similar to what I want, but doesn't quite cover it because a lock will block and the call into my method will pick up as soon as the previous instance releases the lock. That's not what I want to happen because I could potentially end up with a large number of these calls backed up and all waiting to process one by one. Instead, I'd like something similar to a lock, but without the block so that execution will continue after the block of code that would normally be surrounded by the lock.
What I came up with was a counter to be used with Interlocked.Increment and Interlocked.Decrement to allow me to use a simple if statement to determine whether execution on the method should continue.
public class Processor
{
private long _numberOfThreadsRunning = 0;
public void PerformProcessing()
{
long currentThreadNumber Interlocked.Increment(ref _numberOfThreadsRunning);
if(currentThreadNumber == 1)
{
// Do something...
}
Interlocked.Decrement(ref _numberOfThreadsRunning);
}
}
I feel like I'm overthinking this and there may be a simpler solution out there.
You could call Monitor.TryEnter and just continue if it returns false.
public class Processor
{
private readonly object lockObject = new object();
public void PerformProcessing()
{
if (Monitor.TryEnter(lockObject) == true)
{
try
{
// Do something...
}
finally
{
Monitor.Exit(lockObject);
}
}
}
}
How about adding a flag to the object. In the method set the flag true to indicated the method is being executed. At the very end of the method, reset it to false. Then you could check the status of the flag to know if the method can be called.
I suspect this is a very dumb question: what is the correct syntax for an interruptible lock statement in C#? E.g. get lock; if lock is interrupted before locked code finishes, return false out of the enclosing method. Probably totally the wrong terminology... Thanks.
You can have a timeout while aquiring a lock using Monitor.TryEnter; and likewise, within a lock you can do things like Monitor.Wait/Monitor.Pulse to temporarily yield the lock, but you can't be interrupted as such.
The main time interrupt applies might be in Thread.Sleep, which can be interrupted with Thread.Interrupt - but again, this won't yank control out of an executing method block.
What exactly is it that you are trying to achieve? With more context we can probably help more...
What you mean by "interrupted" is unclear.
Interruption by Exception
private bool SomeLockingMethod(object foo)
{
// Verify foo is valid
try
{
lock(foo)
{
while(something)
{
// Do stuff
Thread.Sleep(1); // Possibly yield to another
// thread calling Thread.Interrupt
}
}
return true;
}
catch(ThreadInterruptedException ex)
{
// Handle exception
}
return false;
}
If the return true isn't reached, then something happened while the lock on foo was held, and the code returns false. The lock is automatically released, either way.
Another thread can interrupt this one by calling Thread.Interrupt.
"Interruption" from code
If you're the one "interrupting" the code, it could be as simple as
private bool SomeLockingMethod(object foo)
{
// Verify foo is valid
lock(foo)
{
// Do stuff
if(shouldInterrupt)
{
return false;
}
// Do more stuff
}
return true;
}
Again, the lock is automatically released, whether or not there is an "interruption".
Interruption because someone else is trying to acquire the lock
Possibly this is what you're looking for; in this case you may want to use something else, like a Semaphore or ManualResetEvent.
I'm not sure what you're trying to get at here. The purpose of the lock statement is that you should not get interrupted so you can ensure consistent behavior.
What are you trying to accomplish here?
You might also have a look at transaction scope, added in 2.0, which may be what you're looking for (unknown, due the ambiguity in your question). It allows you to attempt some actions, then roll back if those actions were not completed properly.
See here for more details.