【问题标题】:class expose event, how to know if someone subscribed it类公开事件,如何知道是否有人订阅了它
【发布时间】:2013-06-03 08:28:19
【问题描述】:

我的班级实现了接口,我将事件暴露给外界。
我有一个轮询计时器,它使用该事件使用自定义 eventArgs 向订阅者发送数据。
我想仅在有人订阅事件时启动轮询计时器,并在每个人都取消订阅时停止计时器。
如何检测某人何时订阅/取消订阅我的活动?

这样,如果没有人听,我可以自动启动/停止轮询计时器。

【问题讨论】:

标签: c# events


【解决方案1】:

您可以添加自己的add/remove 方法;例如:

private EventHandler someEvent;
public event EventHandler SomeEvent {
    add {
        someEvent += value;
        if(someEvent != null) EnsureTimerRunning();
    }
    remove {
        someEvent -= value;
        if(someEvent == null) StopTimerIfRunning();
    }
}

请注意,类字段事件(即public event EventHandler SomeEvent;)包括编译器生成的围绕add/remove 的线程安全 - 您需要决定是否复制它,并且如果是这样:如何(lockInterlocked,或者只是推迟到类似私有支持字段的事件并让编译器担心)。一个非常简单的方法可能是:

private EventHandler someEvent;
private readonly object syncLock = new object();
public event EventHandler SomeEvent {
    add {
        lock(syncLock) {
            someEvent += value;
            if(someEvent != null) EnsureTimerRunning();
        }
    }
    remove {
        lock(syncLock) {
            someEvent -= value;
            if(someEvent == null) StopTimerIfRunning();
        }
    }
}

【讨论】:

  • 感谢您的回答,所以它们被称为事件访问器。我知道除了使用 GetInvocationList() 之外,一定有更好的方法。
  • @ilansch 调用列表很方便,但在“有/没有订阅者”的情况下,这只是一个null 测试
  • 如果我实现了添加/删除,我不能再检查 someEvent != null。我需要添加额外的“get”访问器吗?
  • 行锁(syncLock) { someEvent -= value; if(someEvent == null) StopTimerIfRunning();会告诉我: someEvent 只能出现在 +/-= 的左侧
  • @ilansch 不,不是;这是一个私人领域和公共事件;这绝对是不是私人活动和公共财产
猜你喜欢
  • 2011-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-17
  • 1970-01-01
  • 2019-10-10
  • 2011-06-12
  • 2014-11-18
相关资源
最近更新 更多