一尘不染

监控与锁定

c#

什么时候在C#中使用Monitor类或lock关键字来确保线程安全?

编辑: 从到目前为止的答案看来,这lock是对该Monitor课程的一系列电话的简称。锁定调用简写的确切含义是什么?更明确地说,

class LockVsMonitor
{
    private readonly object LockObject = new object();
    public void DoThreadSafeSomethingWithLock(Action action)
    {
        lock (LockObject)
        {
            action.Invoke();
        }
    }
    public void DoThreadSafeSomethingWithMonitor(Action action)
    {
        // What goes here ?
    }
}

更新资料

谢谢大家的帮助:作为您提供的某些信息的后续,我还发布了另一个问题。由于您似乎精通此领域,因此我发布了链接:锁定和管理锁定异常的解决方案有什么问题?


阅读 242

收藏
2020-05-19

共1个答案

一尘不染

埃里克·利珀特(Eric Lippert)在他的博客中谈到了这一点: 锁和异常不会混在一起

等效代码在C#4.0和早期版本之间有所不同。


在C#4.0中,它是:

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

Monitor.Enter采取锁定时,它依赖于自动设置标志。


之前是:

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

这不依赖于Monitor.Enter和之间抛出异常try。我认为在调试代码中违反了这种情况,因为编译器在它们之间插入了NOP,从而使两者之间的线程中止成为可能。

2020-05-19