2016-04-21 12 views
-2

我有一种情况,多个类正在注册与另一个类的兴趣,观察某个属性的值。这是正在使用委托像这样做:C#检查委托/ func是否有一个有效的接收器

public delegate void ObservingHandler (object value); 

Dictionary<ObservingHandler, ObservationInfo> _handlers = new Dictionary<ObservationHandler, ObservationInfo>(); 

public void register(ObservingHandler handler) { 

    // Observation info is created here and is just a struct 
    _handlers.Add(handler, info); 
} 

这个伟大的工程,是真正有用的,但目前在已注册的对象被释放它告诉相关的类,它不再想收到通知。否则,我会得到NULL引用异常。

目前这意味着我不能使用lambda表达式,因为观察处理程序是字典中的键(因此在删除它时需要是相同的实例)。

我想要做的是检查每个ObservationHandler在它被调用之前是否有一个有效的实例化类。这样一来,责任就从听课中消失了。

有没有办法在Funcdelegate检查接收器的功能是否还活着?

编辑:

完整的源代码来自我的项目叫SFCore on GitHub

+2

“否则我得到excetpions” - 什么例外?这不太清楚你的意思 - 请展示一个证明问题的[mcve]。 –

+0

'ObservingHandler'是对观测类中方法的引用。如果observing类被释放,那么'ObservingHandler'包含一个对null类中方法的引用。我相信这个异常是一个空引用异常。所以现在我必须让观测类在发布前取消注册,但是我希望能够判断ObservingHandler是否有一个实例化的观察者。 –

+0

而不是“相信”异常是一个NullReferenceException,为什么不向我们展示一个例子?我期望ObservingHandler引用可以自动保持目标活动 - 这里没有“发布”。基本上,直到你能够以简明的形式重现问题,要帮助你将会非常困难。 –

回答

1

我会使用.NET事件模型,让责任留在监听器中,毕竟如果您的测试因任何原因失败,您的接收器将不会再被通知。

我会做的,是在通知听众的同时,捕捉可能出现的任何异常。

如果发生异常是由于类不再存在(不能更具体地说明您没有给我们确切的异常名称),那么您将忽略它(认为它只是一次性的错误)或从字典中删除它。

这就是我所要做的,肯定有其他方法来实现这一点。

+0

谢谢,这是一个好主意。有没有什么方法可以在通知听众之前告诉听众是否真的存在?我假设'事件'这样做,但我不知道如何。 –

0

Observer pattern in C#是通过事件实现的。 根据您的描述建议使用event关键字。

您不需要像在示例中那样持续跟踪持有字典级别的回调。你在电话中所做的一切就是:开展活动。

+0

但是你仍然需要检查什么时候触发了你有观察者的事件,如果你不这样做,你会有一些不错的'NullReferenceException' – Sidewinder94

+1

如果你总是至少有一个侦听器,那么你不需要检查:事件EventHandler MyEvent =(s,e )=> {}; –

+0

那么我采取了在这些情况下检查null的习惯:) 但是,这是另一种方式来看它 – Sidewinder94