Can Monitor.Enter throw an exception?

China☆狼群 提交于 2019-12-22 06:51:11

问题


Can Monitor.Enter throw any exception. I am doing a code review and find that Monitor.Enter is before try block. Do you see any issues with in?

Monitor.Enter(...)
try
{
    ...
}
finally
{
    Monitor.Exit(..)
}

回答1:


This is the correct pattern, whether Enter() throws (can throw) or not.

Only after the call to Enter() succeeds your code is under the responsibility to call Exit().

Suppose the call to Enter() fails. Then calling the corresponding Exit() is simply incorrect, it will make matters worse. So Enter() has to be outside (before) the try block.




回答2:


Hans Passant's comment is of course correct. If Monitor.Enter throws before the lock is taken then you do not want the finally to run. If it throws after the lock is taken and after the try is entered, then the lock is released. (More on this later.) But if the throw happens after the lock is taken but before the try is entered, then the lock will never be cleaned up.

This is a rare but possible situation.

In C# 4 we changed the codegen of the lock statement so that the monitor enter is inside the try. This ensures that the lock is always released if something throws after the lock is taken. However, note that this might still be wrong. If something throws after the lock is taken then whatever non-atomic mutation the lock is protecting might be half-completed, and the finally block then unlocks the lock and allows access to the inconsistent state! The fundamental problem here is that you shouldn't be throwing inside a lock in the first place.

See my article about the issue for more discussion.




回答3:


Monitor.Enter can throw at least the following exceptions

  • ArgumentNullException of the parameter is null
  • ThreadInterruptedException if the thread doing the Enter has it's Interrupt method invoked.



回答4:


If it acquires the lock, then no.

But an exception might be thrown between the Monitor.Enter and the try block.

The recommended method is the new Enter method, new in .NET 4:

public static void Enter( obj, ref bool lockTaken )


来源:https://stackoverflow.com/questions/8840225/can-monitor-enter-throw-an-exception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!