代码之家  ›  专栏  ›  技术社区  ›  Benny

我应该锁定“事件”吗?

  •  13
  • Benny  · 技术社区  · 15 年前

    在以下情况下,是否应锁定事件:

    事件FO;

    线程A:将调用foo+=handler;

    线程B:将调用foo-=handler;

    我应该锁上foo吗?

    1 回复  |  直到 12 年前
        1
  •  24
  •   Jon Skeet    15 年前

    锁定 foo 是个坏主意,因为值每次都会改变。你应该锁定一个变量 变化:

    private readonly object eventLock = new object();
    private EventHandler fooHandler;
    
    public event EventHandler Foo
    {
        add
        {
            lock (eventLock)
            {
                fooHandler += value;
            }
        }
        remove
        {
            lock (eventLock)
            {
                fooHandler -= value;
            }
        }
    }
    
    private void OnFoo(EventArgs e)
    {
        EventHandler handler;
        lock (eventLock)
        {
            handler = fooHandler;
        }
        if (handler != null)
        {
            handler(this, e);
        }
    }
    

    请注意,如果使用类似字段的事件,则如下所示:

    public event EventHandler Foo;
    

    然后,您将在添加/删除时自动获得一个“lock(this)”,尽管在调用处理程序之前,您必须在获取处理程序时手动添加它(假设您希望确保读取最近写入的值)。就我个人而言,我不喜欢锁定“this”,但你可能不介意——而且它当然可以使代码更简单。