C#为什么我的锁声明挂了?

Mar*_*ijn 4 .net c# locking

我已经学习了一些关于如何创建custem事件访问器的教程.这是我的代码:

event ControlNameChangeHandler IProcessBlock.OnControlNameChanged
{
    add
    {
        lock (ControlNameChanged)
        {
            ControlNameChanged += value;
        }
    }
    remove
    {
        lock (ControlNameChanged)
        {
            ControlNameChanged -= value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在代码到达lock(ControlNameChanged)添加元素时,没有任何反应.代码不再运行.但是我的申请仍然有效.它不冻结或什么的.

出了什么问题?

Luc*_*ero 13

不知何故,其他人持有锁.您不应该使用多播委托实例或事件来进行锁定,也不应该使用公共成员,因为您无法控制谁锁定以及何时锁定.

因此我会使用这样的单独锁定对象:

private readonly object controlNameChangedSync = new object();

event ControlNameChangeHandler IProcessBlock.OnControlNameChanged
{
  add
  {
    lock (controlNameChangedSync)
    {
      ControlNameChanged += value;
    }
  }
  remove
  {
    lock (controlNameChangedSync)
    {
      ControlNameChanged -= value;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:在执行委托+=或-=委托时,对事件的引用会发生更改.


eri*_*len 8

你的代码相当于

event ControlNameChangeHandler IProcessBlock.OnControlNameChanged {
    add {
        try {
            Monitor.Enter(ControlNameChanged);
            ControlNameChanged = ControlNameChanged + value;
        }
        finally {
            Monitor.Exit(ControlNameChanged);
        }
    } 
    remove { 
        try {
            Monitor.Enter(ControlNameChanged);
            ControlNameChanged = ControlNameChanged - value;
        }
        finally {
            Monitor.Exit(ControlNameChanged);
        }
    } 
}
Run Code Online (Sandbox Code Playgroud)

请注意,您退出的对象与您输入的对象不同.这意味着你有一个锁从未被释放,一个锁被释放但从未被取走.您应该将代码更改为:

private object padlock = new object();
event ControlNameChangeHandler IProcessBlock.OnControlNameChanged {
    add {
        lock (padlock) {
            ControlNameChanged += value;
        }
    } 
    remove { 
        lock (padlock) {
            ControlNameChanged -= value;
        }
    } 
}
Run Code Online (Sandbox Code Playgroud)