【发布时间】:2012-04-28 14:44:03
【问题描述】:
如果您使用相同的订阅多次订阅 .net 事件,那么您订阅的方法将被调用与订阅相同的时间。而且,如果您只取消订阅一次,那么通话只会减一分。这意味着您必须取消订阅的次数与订阅的次数相同,否则您将收到通知。有时你不想这样做。
为了防止一个事件处理程序被钩住两次,我们可以如下实现事件。
private EventHandler foo;
public event EventHandler Foo
{
add
{
if( foo == null || !foo.GetInvocationList().Contains(value) )
{
foo += value;
}
}
remove
{
foo -= value;
}
}
现在我想实现 Postsharp EventInterceptionAspect 以使这个解决方案通用,这样我就可以在每个事件上应用 PreventEventHookedTwiceAttribute 以节省大量代码。但我不知道如何在 add.xml 中检查以下条件的第二部分。我的意思是 foo.GetInvocationList().Contains(value)。我的 PreventEventHookedTwiceAttribute 如下所示。
[Serializable]
public class PreventEventHookedTwiceAttribute: EventInterceptionAspect
{
public override void OnAddHandler(EventInterceptionArgs args)
{
if(args.Event == null || secondConditionRequired) // secondConditionRequired means it is required.
{
args.ProceedAddHandler();
}
}
}
我不需要重写 OnRemoveHandler,因为这里的默认功能就足够了。
【问题讨论】:
-
您不希望同一个订阅者订阅两次,还是只想要一个订阅期?
-
@DustinDavis:感谢您的提问。我想防止同一个订阅者订阅两次。像这个例子: void EventHandler(){.....} Main() { someClass.SomeEvent += EventHandler; someClass.SomeEvent += EventHandler;如果我使用普通事件,那么 EventHandler 方法将被调用两次。但是如果我使用 Foo 中实现的模式,那么它只会被调用一次。
-
@DustinDavis:我解决了这个问题。请看我的回答。
标签: c# event-handling postsharp