同步结果

Jam*_*mes 5 c#

为什么 IAsyncResult 要求我保留对 BeginInvoked 它的委托的引用?

我希望能够写出类似的东西:

new GenericDelegate(DoSomething).BeginInvoke(DoSomethingComplete);

void DoSomethingComplete(IAsyncResult ar)
{
    ar.EndInvoke();
}
Run Code Online (Sandbox Code Playgroud)

Gre*_*ech 5

在执行普通的1委托时,您不需要保留自己对委托的引用BeginInvoke;您可以将 转换IAsyncResult为 anAsyncResult并从AsyncDelegate属性中检索委托。在有人说“这是一个肮脏的黑客”之前,它在 MSDN 上被记录为有效

AsyncResult 类与使用委托进行的异步方法调用结合使用。从委托的 BeginInvoke 方法返回的 IAsyncResult 可以转换为 AsyncResult。AsyncResult 具有 AsyncDelegate 属性,该属性保存调用异步调用的委托对象。

所以你可以写:

new GenericDelegate(DoSomething).BeginInvoke(DoSomethingComplete);

void DoSomethingComplete(IAsyncResult ar)
{
    ((GenericDelegate)((AsyncResult)ar).AsyncDelegate)).EndInvoke();
}
Run Code Online (Sandbox Code Playgroud)

请注意,您仍然必须知道原始委托的类型(或者至少,我还没有找到解决此限制的方法;然后我还没有尝试过)。


1这里的“正常”是指BeginInvoke在委托实例上使用编译器生成的方法。AsyncResult当使用预定义的方法时,即使用声明自己的BeginX/EndX方法的类时,不能保证这种强制转换技术有效。这是因为该类可能在内部做一些更聪明的事情,例如阻塞 IO 完成端口,因此可能使用不同类型的IAsyncResult. 但是,在假设的场景中,它会正常工作。