c# - 锁定对象

标签 c# locking

我经常看到这样的代码 shown here ,即对象被分配然后用作“锁定对象”的地方。

在我看来,您可以为此使用任何对象,包括事件本身作为锁定对象。为什么分配一个什么都不做的新对象?我的理解是,在一个对象上调用 lock() 实际上并没有改变对象本身,也没有真正锁定它不被使用,它只是用作多个锁定语句的占位符。

public class Shape : IDrawingObject, IShape
{
    // Create an event for each interface event
    event EventHandler PreDrawEvent;
    event EventHandler PostDrawEvent;

    object objectLock = new Object();

    // Explicit interface implementation required.
    // Associate IDrawingObject's event with
    // PreDrawEvent
    event EventHandler IDrawingObject.OnDraw
    {
        add
        {
            lock (objectLock)
            {
                PreDrawEvent += value;
            }
        }
        remove
        {
            lock (objectLock)
            {
                PreDrawEvent -= value;
            }
        }
    }
}

所以我的问题是,这真的是一件好事吗?

最佳答案

including the event itself

不,你不能那样做。 “事件”实际上只是一些访问器方法。假设您指的是支持委托(delegate),那将非常糟糕 - 委托(delegate)是不可变的:每次添加/删除订阅者时,您都会得到一个不同的委托(delegate)。

实际上,4.0 编译器现在使用 Interlocked 使用无锁代码来执行此操作 - 可能值得采用这种方法。

在您的示例中,objectLock 确保所有调用方(对该实例)锁定相同 对象,这很重要 - 但没有锁定的丑陋this(这是 C# 编译器过去的工作方式)。

--

更新:您的示例显示了 C# 4.0 之前必需的代码,访问类字段事件 内部 类型直接与字段对话:普通的类字段事件锁定不是尊重。这在 C# 4.0 中已更改;您现在可以(在 C# 4.0 中)安全地将其重写为:

public class Shape : IDrawingObject, IShape
{
    // Create an event for each interface event
    event EventHandler PreDrawEvent;
    event EventHandler PostDrawEvent;

    event EventHandler IDrawingObject.OnDraw
    {
        add { PreDrawEvent += value; }
        remove { PreDrawEvent -= value; }
    }
}

然后遵循所有正确的行为。

关于c# - 锁定对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2979444/

相关文章:

c# - 检测添加到 ComboBox 的项目的事件

c# - 在 Controller asp.net-core v1.1.0 之外使用 Dependency Injection 进行应用程序设置

c++ - 为什么锁定会减慢顺序文件解析器的速度?

database - 锁定 postgresql 表

c# - 使用深度数据 - Kinect

c# - 是否有一种标准模式可以避免由于单个任务阻塞而导致作业队列延迟?

java - Java应用程序死锁原因查找工具

mongodb - mongodb写锁行为

c# - NHibernate 中的 QueryOver

javascript - 锁定同时 JavaScript 调用