What happens if I call Dispose () on a locked object?
Firstly, the object itself is not locked (protected) to begin with. The link used in the lock key is used to mark or mark a section of code that should not be launched simultaneously with any other (or the same) part of the code that used the same object link. This does not actually affect the object itself. This is a fairly common misconception about how locks work in .NET.
In this context, calling Dispose is no different than calling any other method. Nothing special happens. It just means that two different threads cannot execute Dispose at the same time. What you do is not only acceptable, but really recommends if the class is not thread safe.
And what happens if I miss the call to Monitor.Exit () in this case:
You should always let go of locks. Keeping in mind that locks do not affect an object link, it should be easier to understand that you will leave the lock in the acquired state. It does not matter that the object is located. Remember that Monitor (or lock ) does not lock or protect the object itself. It only marks or marks a section of code. If a thread tries to obtain a lock with the same object again, this thread will be forced to wait indefinitely, which can lead to a deadlock.
A more interesting question: can this lead to a memory leak. Does Monitor.Enter root of an object? The answer is no. This can be demonstrated in the following example.
public class Program { public static void Main(string[] args) { var foo = new Foo(); Monitor.Enter(foo); foo = null; GC.Collect(); GC.WaitForPendingFinalizers(); Console.ReadLine(); } } internal class Foo { ~Foo() { Console.WriteLine("~Foo"); } }
If you compile and run this, you will see that "~ Foo" is printed. This suggests that Monitor.Enter does not contain a link inside. Therefore, although it is not recommended to skip the Monitor.Exit call, you may feel some comfort knowing that it will not cause a memory leak. 1
1 Actually, this may not be entirely true. Although it is fairly easy to demonstrate that a managed memory leak cannot be otherwise, in an unmanaged area it can be different. Despite the SSCLI code, we really don't know what Monitor.Enter does internally. Perhaps it allocates one additional array slot (or something else) in an unmanaged heap or stack. I would like to think that Microsoft has considered this obscure scenario, but who knows. The fact is that the calls Monitor.Enter and Monitor.Exit should always be paired so that you do not have to worry about it.