使用IDisposable取消订阅事件 [英] Using IDisposable to unsubscribe events

查看:213
本文介绍了使用IDisposable取消订阅事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类来处理来自WinForms控件的事件。基于用户正在做什么,我引用类的一个实例并创建一个新的类来处理相同的事件。我需要从事件中取消订阅旧的实例 - 足够简单。如果可能,我想以非专有方式执行此操作,并且看起来这是一个IDisposable的工作。但是,大多数文档仅在使用非托管资源时才推荐使用IDisposable,这不适用于此。



如果我实现了IDisposable并取消订阅Dispose()中的事件,其意图?我应该提供一个取消订阅()函数并调用吗?






编辑:虚拟代码,显示我在做什么(使用IDisposable)。我的实际实现与一些专有数据绑定(长篇故事)有关。

  class EventListener:IDisposable 
{
private TextBox m_textBox;

public EventListener(TextBox textBox)
{
m_textBox = textBox;
textBox.TextChanged + = new EventHandler(textBox_TextChanged);
}

void textBox_TextChanged(object sender,EventArgs e)
{
//做某事
}

public void Dispose()
{
m_textBox.TextChanged - = new EventHandler(textBox_TextChanged);
}
}

class MyClass
{
EventListener m_eventListener = null;
TextBox m_textBox = new TextBox();

void SetEventListener()
{
if(m_eventListener!= null)m_eventListener.Dispose();
m_eventListener = new EventListener(m_textBox);
}
}

在实际代码中,EventListener类是更多的涉及,每个实例都是独一无二的。我在一个集合中使用这些,并在用户点击时创建/销毁它们。






结论



我接受 gbjbaanb的答案,至少现在。我觉得使用一个熟悉的界面的好处超过了使用它的任何可能的缺点,没有涉及非托管代码(这个对象的用户甚至会知道什么?)。



如果有人不同意 - 请发表/评论/编辑。如果可以对IDisposable做出更好的论证,那么我会更改接受的答案。

解决方案

是的,去吧。虽然有些人认为IDisposable仅用于非托管资源,但情况并非如此 - 非托管资源恰好是最大的胜利,也是最明显的理由。我认为它获得了这个想法,因为人们不能想到任何其他的理由来使用它。它不像一个性能问题的定稿器,GC不容易处理。



将任何整理代码放在处理方法中。它会更清晰,更清洁,更有可能防止内存泄漏,并且更容易使用正确的视线,而不是设法避免您的引用。



IDisposable的意图是使您的代码工作更好,而无需进行大量的手动工作。使用它的权力,并获得一些人为的设计意图废话。



我记得很难说服微软确定性终结的有用性。 NET首先出来 - 我们赢了战斗并说服他们添加它(即使它只是当时的设计模式),使用它!


I have a class that handles events from a WinForms control. Based on what the user is doing, I am deferencing one instance of the class and creating a new one to handle the same event. I need to unsubscribe the old instance from the event first - easy enough. I'd like to do this in a non-proprietary manner if possible, and it seems like this is a job for IDisposable. However, most documentation recommends IDisposable only when using unmanaged resources, which does not apply here.

If I implement IDisposable and unsubscribe from the event in Dispose(), am I perverting its intention? Should I instead provide an Unsubscribe() function and call that?


Edit: Here's some dummy code that kind of shows what I'm doing (using IDisposable). My actual implementation is related to some proprietary data binding (long story).

class EventListener : IDisposable
{
    private TextBox m_textBox;

    public EventListener(TextBox textBox)
    {
        m_textBox = textBox;
        textBox.TextChanged += new EventHandler(textBox_TextChanged);
    }

    void textBox_TextChanged(object sender, EventArgs e)
    {
        // do something
    }

    public void Dispose()
    {
        m_textBox.TextChanged -= new EventHandler(textBox_TextChanged);
    }
}

class MyClass
{
    EventListener m_eventListener = null;
    TextBox m_textBox = new TextBox();

    void SetEventListener()
    {
        if (m_eventListener != null) m_eventListener.Dispose();
        m_eventListener = new EventListener(m_textBox);
    }
}

In the actual code, the "EventListener" class is more involved, and each instance is uniquely significant. I use these in a collection, and create/destroy them as the user clicks around.


Conclusion

I'm accepting gbjbaanb's answer, at least for now. I feel that the benefit of using a familiar interface outweighs any possible downside of using it where no unmanaged code is involved (how would a user of this object even know that?).

If anyone disagrees - please post/comment/edit. If a better argument can be made against IDisposable, then I'll change the accepted answer.

解决方案

Yes, go for it. Although some people think IDisposable is implemented only for unmanaged resources, this is not the case - unmanaged resources just happens to be the biggest win, and most obvious reason to implement it. I think its acquired this idea because people couldn't think of any other reason to use it. Its not like a finaliser which is a performance problem and not easy for the GC to handle well.

Put any tidy-up code in your dispose method. It'll be clearer, cleaner and significantly more likely to prevent memory leaks and a damn sight easier to use correctly than trying to remember to un-do your references.

The intention of IDisposable is to make your code work better without you having to do lots of manual work. Use its power in your favour and get over some artificial "design intention" nonsense.

I remember it was difficult enough to persuade Microsoft of the usefulness of deterministic finalisation back when .NET first came out - we won the battle and persuaded them to add it (even if it was only a design pattern at the time), use it!

这篇关于使用IDisposable取消订阅事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆