如何在C#中可以清楚我的事件订阅?如何在C#中可以清楚我的事件订阅?(How can I clear

2019-05-13 01:02发布

看看下面的C#类:

c1 {
 event EventHandler someEvent;
}

如果有大量的订阅到c1someEvent事件,我想清楚了他们,什么是实现这一目标的最佳途径? 同时认为,订阅此事件可能是/是lambda表达式/匿名委托。

目前,我的解决办法是增加一个ResetSubscriptions()方法,以c1 ,设置someEvent为null。 我不知道这有什么看不见的后果。

Answer 1:

从类中,你可以设置(隐藏)变量设置为null。 空引用是代表一个空的调用列表,有效的规范方式。

从类以外,你不能做到这一点 - 事件基本上暴露“订阅”及“取消订阅”,就是这样。

这是值得意识到什么的现场般的事件,实际上是做-他们正在创建一个变量,并在同一时间的事件。 在类,你最终引用变量。 从外面,你引用的事件。

见我对事件和委托的文章以了解更多信息。



Answer 2:

一个方法添加到C1,将设置“someEvent”为空...

class c1
{
    event EventHandler someEvent;
    ResetSubscriptions() {someEvent = null;}
}


Answer 3:

class c1
{
    event EventHandler someEvent;
    ResetSubscriptions() {someEvent = delegate{};}
}

这是更好地使用委托{}比空



Answer 4:

设置事件类作品里面空。 当您处理一个类,你应该始终设置事件为空时,GC与事件的问题,如果它已经晃来晃去的事件可能不会清理处置类。



Answer 5:

清除所有用户的最佳做法是通过增加另一个公开的方法,如果你想公开此功能外设置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.
    }


Answer 6:

您可以通过使用Delegate.Remove或Delegate.RemoveAll方法实现这一目标。



Answer 7:

概念延长无聊的评论。

我宁愿用“事件处理程序”,而不是“事件”或“代表”。 和所使用的“事件”一词用于其他的东西。 在一些编程语言(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)。



Answer 8:

这是我的解决方案:

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()){/*...*/}模式退订调用列表中的所有成员。



Answer 9:

删除所有事件,假设该事件是一个“动作”类型:

Delegate[] dary = TermCheckScore.GetInvocationList();

if ( dary != null )
{
    foreach ( Delegate del in dary )
    {
        TermCheckScore -= ( Action ) del;
    }
}


文章来源: How can I clear event subscriptions in C#?