【问题标题】:What's the advantage of Monitor.Enter(object, ref bool) over Monitor.Enter(object)?Monitor.Enter(object, ref bool) 与 Monitor.Enter(object) 相比有什么优势?
【发布时间】:2012-06-07 15:37:12
【问题描述】:

根据语言规范lock(obj) statement; 将被编译为:

object lockObj = obj; // (the langspec doesn't mention this var, but it wouldn't be safe without it)
Monitor.Enter(lockObj);
try
{
    statement;
}
finally
{
    Monitor.Exit(lockObj);
}

但是编译为:

try
{
    object lockObj = obj;
    bool lockTaken = false;
    Monitor.Enter(lockObj, ref lockTaken);
    statement;
}
finally
{
    if (lockTaken) Monitor.Exit(lockObj);
}

这似乎比必要的复杂得多。那么问题来了,这种实现有什么好处呢?

【问题讨论】:

    标签: c# c#-4.0 concurrency c#-3.0


    【解决方案1】:

    一如既往,Eric Lippert 已经回答了这个问题:

    Fabulous Adventures In Coding: Locks and exceptions do not mix

    【讨论】:

    • 我正要回答自己,因为我想了另一个答案,不幸的是,在我发表评论之前就被删除了。让我更多地思考什么时候可以抛出异常,线程可能在任何地方被中断等等。很明显Monitor.Enter 可以成功返回,但是在线程进入try 块之前它可能会被中断。有时,这个网站速度太快,无法向所有帮助找到答案的人致敬。
    • 链接已失效。到今天为止,这篇文章可以在这里找到:ericlippert.com/2009/03/06/locks-and-exceptions-do-not-mix
    【解决方案2】:

    最近我在“通过 C# 的 CLR”中读到它实际上可能并不是一个优势。原因是finally 块总是释放锁定的资源,即使try 块由于意外错误而退出。这可能会使资源处于未定义状态并且可以访问。程序不会死锁,但错误可能更微妙,因此更难找到。

    这当然取决于具体情况,但我想如果您的优先级是防止在最坏的情况下由于线程意外中断而导致死锁,那么lock 的当前实现最有意义。

    【讨论】:

      猜你喜欢
      • 2013-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-04
      • 2011-03-13
      • 1970-01-01
      • 1970-01-01
      • 2011-02-19
      相关资源
      最近更新 更多