c#lock return / continue / break

时间:2012-02-10 12:53:51

标签: c# multithreading locking

如果我有以下代码:

lock(SyncRoot){ return value; }

在返回语句之前是否会解锁SyncRoot?

我试过浏览VS2005中的代码,但它实际上并没有显示出这样或那样的方式。它似乎解锁了,但我想确定。

7 个答案:

答案 0 :(得分:3)

是的,无论你如何退出街区(即返回,休息,投掷等),它都会解锁。

有关详细信息,请参阅MSDN - lock statement

  

lock关键字确保一个线程不进入代码的关键部分,而另一个线程处于临界区   ...
  lock关键字在块的开头调用Enter,在   块结束。

答案 1 :(得分:3)

是的,你可以把它想象成这样的东西:

Monitor.Enter(obj);
try {
    var result = value;
}
finally {
    Monitor.Exit(obj);
}
return result;

如果你看一下生成的IL,就是这样的。如果value是表达式,则会在释放锁之前对其进行评估。释放锁后执行返回。

在任何情况下都会调用finally块,所以是的,锁被释放。

答案 2 :(得分:2)

是的,它会计算值(如果值是一个表达式,这可能很重要),然后解锁并返回。无论你如何操作,当你退出其范围时,lock()总是自动解锁。

答案 3 :(得分:2)

请注意,lock实际上在后台使用Monitor.Enter / Monitor.Exit。您的代码的扩展版本实际上就是

Monitor.Enter (SyncRoot);
try
{
    return value;
}
finally { Monitor.Exit (SyncRoot); }

保证finally块在方法实际返回之前执行,因此锁被释放。

答案 4 :(得分:1)

块执行后会解锁。

此语法类似于using,顺便说一句。 lock在块之外的唯一原因是显示启动时锁定,结束时解锁功能。

答案 5 :(得分:1)

如果你有类似`的东西             int i = 0;             object o = new object();

        while (i < 100)
        {
            lock (o)
            {
                if (i == 10)
                    continue;
            }

            ++i;
        }`

这会导致死锁,因为 它将永远等待获得 锁定从上一次执行中保存 继续之前的上下文

答案 6 :(得分:0)

不,只有返回语句后才会释放锁。