c# - 锁定关键字调用 Monitor.Enter(Object) 或 Enter(Object, Boolean)?

标签 c# .net locking monitor

Monitor .NET Framework 4.5的文档我找到了一句话,说lock关键字使用Enter(Object, Boolean)监听方法:

The functionality provided by the Enter and Exit methods is identical to that provided by the C# lock statement (SyncLock in Visual Basic), except that lock and SyncLock wrap the Enter(Object, Boolean) method overload and the Exit method in a try…finally block (Try…Finally in Visual Basic) to ensure that the monitor is released.

另一方面,在Monitors的概览中有:

The Visual Basic SyncLock and C# lock statements use MonitorEnter to take the lock and MonitorExit to release it.

上面的MonitorEnter指的是与之前不同版本的Enter方法,即:Enter(Object)

Thread Synchronization (C# and Visual Basic)对于 Visual Studio 2012,有一个锁如何包装监视器的示例:

System.Object obj = (System.Object)x;
System.Threading.Monitor.Enter(obj);
try
{
    DoSomething();
}
finally
{
    System.Threading.Monitor.Exit(obj);
}

还有Enter(Object)版本。

什么是真的? 是否锁定语句调用 Enter(Object, Boolean)Enter(Object) ? 到底是怎么做到的,有什么不同吗?

最佳答案

来自 Eric Lippert’s Blog :

Recall that lock(obj){body} was [in C# 3.0 and earlier] a syntactic sugar for

var temp = obj;
Monitor.Enter(temp);
try { body }
finally { Monitor.Exit(temp); }

The problem here is that if the compiler generates a no-op instruction between the monitor enter and the try-protected region then it is possible for the runtime to throw a thread abort exception after the monitor enter but before the try. In that scenario, the finally never runs so the lock leaks, probably eventually deadlocking the program. It would be nice if this were impossible in unoptimized and optimized builds.

In C# 4.0 we've changed lock so that it now generates code as if it were

bool lockWasTaken = false;
var temp = obj;
try { Monitor.Enter(temp, ref lockWasTaken); { body } }
finally { if (lockWasTaken) Monitor.Exit(temp); }

The problem now becomes someone else's problem; the implementation of Monitor.Enter takes on responsibility for atomically setting the flag in a manner that is immune to thread abort exceptions messing it up.

So everything is good now, right?

Sadly, no. [...]

另一方面,C# 4.0 Language Specification说:

A lock statement of the form

lock (x) ...

where x is an expression of a reference-type, is precisely equivalent to

System.Threading.Monitor.Enter(x);
try {
   ...
}
finally {
   System.Threading.Monitor.Exit(x);
}

except that x is only evaluated once.

关于c# - 锁定关键字调用 Monitor.Enter(Object) 或 Enter(Object, Boolean)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15023862/

相关文章:

c# - 在控制台应用程序中打开 pdf 文件

c# - 如何搜索Blob容器的文件内容?

c# - 从文本框中提取部分文本

c# - 使用异步,等待 VS2013 目标 - .NET 4

c# - 试图使用 Crypto 混淆我的项目破坏了它

C++ ifstream 尝试在写入时打开文件

c# protect a database connection string in Settings 防止反编译?

.net - DDD 和客户端验证

c# - 如果队列未锁定,多线程的性能与全局队列的长度有关?

mysql - 如何在并发环境下正确锁定MYSQL表