This may occur under the following circumstances. Suppose you have
Enter(); try { Foo(); } finally { Exit(); }
and a thread interruption exception is thrown after Enter, but before trying. Now the monitor has been introduced, but finally it will never be executed because an exception was thrown before the attempt.
We fixed this flaw in C # 4. In C # 4, the lock statement is now generated as
bool mustExit = false; try { Enter(ref mustExit); Foo(); } finally { if (mustExit) Exit(); }
Things can still go horribly wrong, of course; interruption of the thread does not guarantee that the thread is ever interrupted, which finally blocks the start-up and so on. You may end up in the unhandled exception handler with a locked lock. But it is at least a little better.
source share