当我完成时,`using`断开事件

时间:2013-10-28 20:32:38

标签: c#

我目前有这样的代码,一个async方法:

MyEventHandler handler = (sender, e) => ...

Foo.My += handler;

await Foo.Bar();  // Fires event `My` 

Foo.My -= handler;

我想使用using语句来处理此代码的前后性质。也许有点像:

using (ListenUntilDispose(Foo.My, handler))
{
    await Foo.Bar();
}

但我无法想出写ListenTemporarily

有办法做到这一点吗?

1 个答案:

答案 0 :(得分:1)

是的,有,但不幸的是,这并不是直截了当地做到这一点,因为事件没有在C#中实现 - 我的意思是,你不能传递对事件的引用。

在Reactive Extensions中,这可以通过使用反射来解决,因此您可以通过传递定义的对象以及事件的名称作为字符串将事件传递给函数:

using(ListenUntilDispose(Foo, "My", handler))
{
    await Foo.Bar();
}

但是,我的反射功能并不强大,而且你也失去了静态类型的安全性,这意味着编译器无法检查handler是否真的与Foo.My匹配。如果您的目标确实是“我想使用using”而不一定是“我想要最易读的解决方案”,那么另一个建议并不适合您,但也可能适合您:

class DelegateDisposable : IDisposable
{
    private readonly Action m_dispose;
    public DelegateDisposable(Action onDispose)
    {
        m_dispose = onDispose;
    }

    public void Dispose()
    {
        m_dispose();
    }
}

用法是:

Foo.My += handler;
using(new DelegateDisposable(() => Foo.My -= handler))
{
    await Foo.Bar();
}

免责声明:写在编辑框中,未经测试:)