2

我目前有这样的代码,一个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

有没有办法做到这一点?

4

1 回答 1

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();
}

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

于 2013-10-28T20:49:33.197 回答