如何在C#中清除事件订阅?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在C#中清除事件订阅?相关的知识,希望对你有一定的参考价值。
参加以下C#课程:
c1 {
event EventHandler someEvent;
}
如果有很多订阅c1
的someEvent
事件并且我想要清除它们,那么实现这一目标的最佳方法是什么?还要考虑对此事件的订阅可以是lambdas / anonymous delegates。
目前我的解决方案是将ResetSubscriptions()
方法添加到c1
,将someEvent
设置为null。我不知道这是否有任何看不见的后果。
在类中,您可以将(hidden)变量设置为null。空引用是有效地表示空调用列表的规范方式。
从课外,你不能这样做 - 事件基本上暴露“订阅”和“取消订阅”,就是这样。
值得注意的是,类似字段的事件实际上是在做什么 - 它们同时创建变量和事件。在类中,您最终引用变量。从外面,您可以参考该活动。
有关更多信息,请参阅我的article on events and delegates。
向c1添加一个方法,将'someEvent'设置为null ...
class c1
{
event EventHandler someEvent;
ResetSubscriptions() {someEvent = null;}
}
class c1
{
event EventHandler someEvent;
ResetSubscriptions() {someEvent = delegate{};}
}
使用委托{}比使用null更好
在类中将事件设置为null有效。当你处理一个类时,你应该总是将事件设置为null,GC有事件问题,如果它有悬空事件,可能不会清理已处理的类。
清除所有订阅者的最佳做法是,如果要将此功能公开给外部,可以通过添加另一个公共方法将someEvent设置为null。这没有任何看不见的后果。前提条件是记住使用关键字“event”声明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)中,“event”被称为“message”或“signal”,甚至还有一个“message”关键字和特定的糖语法。
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;
并且,为了响应该“消息”,“事件处理程序”响应,无论是单个委托还是多个委托。
摘要:“事件”是“问题”,“事件处理程序”是答案。
这是我的解决方案:
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()){/*...*/}
模式取消订阅调用列表的所有成员。
Remove all events, assume the event is an "Action" type:
Delegate[] dary = TermCheckScore.GetInvocationList();
if ( dary != null )
{
foreach ( Delegate del in dary )
{
TermCheckScore -= ( Action ) del;
}
}
以上是关于如何在C#中清除事件订阅?的主要内容,如果未能解决你的问题,请参考以下文章
c_cpp UV Index Indicator订阅PubNub并使用颜色显示UV索引值。博文的代码片段。在这里查看项目:https:/