C# 为什么我的 lock 语句挂起?

标签 c# .net locking

我遵循了一些关于如何创建自定义事件访问器的教程。这是我的代码:

event ControlNameChangeHandler IProcessBlock.OnControlNameChanged
{
    add
    {
        lock (ControlNameChanged)
        {
            ControlNameChanged += value;
        }
    }
    remove
    {
        lock (ControlNameChanged)
        {
            ControlNameChanged -= value;
        }
    }
}

在代码到达 add statament 中的 lock(ControlNameChanged) 时,没有任何反应。代码不再运行。但是我的应用程序仍在运行。它不会卡住或其他东西。

出了什么问题?

最佳答案

不知何故,别人持有一把锁。您不应使用多播委托(delegate)实例或事件进行锁定,也不应使用公共(public)成员,因为您无法控制谁在锁定以及何时锁定。

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

private readonly object controlNameChangedSync = new object();

event ControlNameChangeHandler IProcessBlock.OnControlNameChanged
{
  add
  {
    lock (controlNameChangedSync)
    {
      ControlNameChanged += value;
    }
  }
  remove
  {
    lock (controlNameChangedSync)
    {
      ControlNameChanged -= value;
    }
  }
}

注意:在委托(delegate)上执行 +=-= 时,对事件的引用会发生变化。

关于C# 为什么我的 lock 语句挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2026879/

相关文章:

c# - 使用字节数组时的堆碎片

c# - Gmap.Net 中的 map 旋转以使其跟踪

c# - 最优化使用多个 Where 语句

c# - InlineAutoDataAttribute 但对于 NUnit(对于 TestCase 和 TestCaseSource)

.net - 用一个数组(字符串)填充 Excel 范围的 .Formula

c# - 关于使用带有 C# Gui 的 QT 后端的好资源

winapi - 锁定文件但允许当前进程使用?

c# - 是否可以在 VS2012 中创建一个多项目解决方案,其中某些项目已经绑定(bind)到 TFS?

android - 如何以编程方式使用智能锁 Lollipop 关闭屏幕

MySQL/MariaDB InnoDB 同步事务和锁定行为