c#锁定返回/继续/中断

本文关键字:继续 中断 返回 锁定 | 更新日期: 2023-09-27 18:24:05

如果我有以下代码:

lock(SyncRoot){ return value; }

SyncRoot会在return语句之前解锁吗?

我尝试在VS2005中遍历代码,但它实际上并没有以这样或那样的方式显示。看起来它确实解锁了,但我想确定一下。

c#锁定返回/继续/中断

是的,你可以想象它扩展到这样的东西:

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

如果你看看生成的IL,它是这样的。不过,如果value是一个表达式,则会在释放锁之前对其进行求值。解锁后执行返回。

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

是的,无论你如何退出区块(即返回、突破、投掷等),它都会解锁。

有关更多详细信息,请参阅MSDN-lock语句:

lock关键字确保一个线程不进入代码的关键部分,而另一个线程处于关键部分

lock关键字在块的开头调用Enter,在块的末尾。

是的,它计算值(如果值是一个表达式,这可能很重要),然后解锁并返回。锁定()总是在您退出其作用域时自动解锁,无论您如何操作。

请记住,lock实际上在后台使用Monitor.Enter/Monitor.Exit。你代码的扩展版本实际上就是这个
Monitor.Enter (SyncRoot);
try
{
    return value;
}
finally { Monitor.Exit (SyncRoot); }

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

如果您有`int i=0;object o=新对象();

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

这将导致死锁,因为它将永远等待上次执行时保存的锁继续之前的上下文

它将在块执行后解锁。

顺便说一句,这种语法类似于usinglock在块之外的唯一原因是显示开始时有锁定,结束时有解锁功能。

否,只有在返回语句之后才会释放锁。