看看下面的C#类:
c1 {
event EventHandler someEvent;
}
如果有大量的订阅到c1
的someEvent
事件,我想清楚了他们,什么是实现这一目标的最佳途径? 同时认为,订阅此事件可能是/是lambda表达式/匿名委托。
目前,我的解决办法是增加一个ResetSubscriptions()
方法,以c1
,设置someEvent
为null。 我不知道这有什么看不见的后果。
看看下面的C#类:
c1 {
event EventHandler someEvent;
}
如果有大量的订阅到c1
的someEvent
事件,我想清楚了他们,什么是实现这一目标的最佳途径? 同时认为,订阅此事件可能是/是lambda表达式/匿名委托。
目前,我的解决办法是增加一个ResetSubscriptions()
方法,以c1
,设置someEvent
为null。 我不知道这有什么看不见的后果。
从类中,你可以设置(隐藏)变量设置为null。 空引用是代表一个空的调用列表,有效的规范方式。
从类以外,你不能做到这一点 - 事件基本上暴露“订阅”及“取消订阅”,就是这样。
这是值得意识到什么的现场般的事件,实际上是做-他们正在创建一个变量,并在同一时间的事件。 在类,你最终引用变量。 从外面,你引用的事件。
见我对事件和委托的文章以了解更多信息。
一个方法添加到C1,将设置“someEvent”为空...
class c1
{
event EventHandler someEvent;
ResetSubscriptions() {someEvent = null;}
}
class c1
{
event EventHandler someEvent;
ResetSubscriptions() {someEvent = delegate{};}
}
这是更好地使用委托{}比空
设置事件类作品里面空。 当您处理一个类,你应该始终设置事件为空时,GC与事件的问题,如果它已经晃来晃去的事件可能不会清理处置类。
清除所有用户的最佳做法是通过增加另一个公开的方法,如果你想公开此功能外设置someEvent为null。 这有没有看不到的后果。 前提是要记住使用关键字“事件”来声明SomeEvent。
请参阅本书 - C#4.0中概括地说,第125页。
这里有些建议一个使用Delegate.RemoveAll
方法。 如果你使用它,示例代码可以按照下面的表格。 但它是非常愚蠢的。 为什么不SomeEvent=null
内部ClearSubscribers()
函数?
public void ClearSubscribers ()
{
SomeEvent = (EventHandler) Delegate.RemoveAll(SomeEvent, SomeEvent);// Then you will find SomeEvent is set to null.
}
您可以通过使用Delegate.Remove或Delegate.RemoveAll方法实现这一目标。
概念延长无聊的评论。
我宁愿用“事件处理程序”,而不是“事件”或“代表”。 和所使用的“事件”一词用于其他的东西。 在一些编程语言(VB.NET,Object Pascal中,Objective-C中),“事件”被称为“信息”或“信号”,以及甚至有一个“消息”的关键字,和特定的糖语法。
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;
而且,为了给“消息”,一个“事件处理程序”回应响应,无论是单委托或多个委托。
摘要:“事件”是“问题”,“事件处理程序(S)”是答案(S)。
这是我的解决方案:
public class Foo : IDisposable
{
private event EventHandler _statusChanged;
public event EventHandler StatusChanged
{
add
{
_statusChanged += value;
}
remove
{
_statusChanged -= value;
}
}
public void Dispose()
{
_statusChanged = null;
}
}
你需要调用Dispose()
或使用using(new Foo()){/*...*/}
模式退订调用列表中的所有成员。
Delegate[] dary = TermCheckScore.GetInvocationList();
if ( dary != null )
{
foreach ( Delegate del in dary )
{
TermCheckScore -= ( Action ) del;
}
}