我如何清除C#中的事件订阅?
以下面的C#类:
c1 { event EventHandler someEvent; }
如果有很多订阅c1
的someEvent
事件,我想清除它们,最好的方法是什么? 还要考虑这个事件的订阅可能是lambda /匿名代表。
目前我的解决scheme是添加一个ResetSubscriptions()
方法给c1
设置someEvent
为null。 我不知道这是否有任何看不见的后果。
在类中,可以将(隐藏)variables设置为null。 空引用是有效地表示空调用列表的规范方式。
从课外,你不能这样做 – 事件基本上是暴露“订阅”和“取消订阅”,就是这样。
值得注意的是类场事件实际上在做什么 – 它们同时创build一个variables和一个事件。 在课堂上,你最终会引用variables。 从外面,你参考事件。
查看我的关于事件和代表的文章以获取更多信息。
向c1添加一个方法,将'someEvent'设置为null …
class c1 { event EventHandler someEvent; ResetSubscriptions() {someEvent = null;} }
class c1 { event EventHandler someEvent; ResetSubscriptions() {someEvent = delegate{};} }
使用委托{}比null更好
清除所有订阅者的最佳实践是将someEvent设置为null,如果要将此function公开给外部,请添加另一个公共方法。 这没有看不到的后果。 前提是要记住用关键字“event”声明SomeEvent。
请参阅第125页的“C#4.0”一书。
这里有人提议使用Delegate.RemoveAll
方法。 如果您使用它,示例代码可以按照下面的表格。 但这真的很愚蠢。 为什么不在ClearSubscribers()
函数中只是SomeEvent=null
?
public void ClearSubscribers () { SomeEvent = (EventHandler) Delegate.RemoveAll(SomeEvent, SomeEvent);// Then you will find SomeEvent is set to null. }
您可以通过使用Delegate.Remove或Delegate.RemoveAll方法来实现此目的。
在类中设置事件为null。 当你处理一个类的时候,你应该总是把事件设置为null,GC有事件的问题,如果事件悬而未决,可能不会清除已处理的类。
概念延长无聊的评论。
我宁愿使用“事件处理程序”而不是“事件”或“委托”这个词。 其他的东西使用“事件”一词。 在一些编程语言(VB.NET,Object Pascal,Objective-C)中,“event”被称为“消息”或“信号”,甚至有一个“消息”关键字和特定的糖语法。
const WM_Paint = 998; // <-- "question" can be done by several talkers WM_Clear = 546; type MyWindowClass = class(Window) procedure NotEventHandlerMethod_1; procedure NotEventHandlerMethod_17; procedure DoPaintEventHandler; message WM_Paint; // <-- "answer" by this listener procedure DoClearEventHandler; message WM_Clear; end;
而且,为了回应这个“消息”,一个“事件处理程序”响应,不pipe是单个代表还是多个代表。
总结:“事件”是“问题”,“事件处理程序”是答案。
删除所有事件,假设事件是一个“Action”types:
Delegate[] dary = TermCheckScore.GetInvocationList(); if ( dary != null ) { foreach ( Delegate del in dary ) { TermCheckScore -= ( Action ) del; } }