谁将BeginInvoke,Invoke和EndInvoke方法定义添加到类型委托?

时间:2009-03-25 09:24:08

标签: c# delegates

e.g。如果你写...
public delegate void MyTypedDel(int x)
Intellisense显示BeginInvoke,Invoke和EndInvoke是MyTypedDel类型定义的一部分。
它们不是Delegate或MulticastDelegate类型定义的一部分。 (Delegate有一个DynamicInvoke方法,它使用后期/运行时绑定来绑定到方法。)

所以我的问题是这些方法混合到类型委托类型定义中的位置以及它的实现方式如何?我读到了...... Invoke在同一个线程上内部连续调用BeginInvoke和EndInvoke。这是真的吗?

对这里的魔术很好奇..也许我错过了一些非常明显的东西......在这种情况下是残酷的:)

2 个答案:

答案 0 :(得分:5)

编译器生成您的委托类,该类扩展Delegate BCL类并添加特定于委托签名的方法。您可以通过查看反射器中的委托(或BCL委托)并切换到IL视图来看到这一点(因为C#反汇编程序非常智能,可以将其转回委托声明)。例如:

.class public auto ansi sealed WaitCallback
    extends System.MulticastDelegate
{
    .custom instance void System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = { bool(true) }
    .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed
    {
    }

    .method public hidebysig newslot virtual instance class System.IAsyncResult BeginInvoke(object state, class System.AsyncCallback callback, object 'object') runtime managed
    {
    }

    .method public hidebysig newslot virtual instance void EndInvoke(class System.IAsyncResult result) runtime managed
    {
    }

    .method public hidebysig newslot virtual instance void Invoke(object state) runtime managed
    {
    }

}

答案 1 :(得分:1)

编译器完成大部分工作(参见Kent的回复)。关于连续调用Begin / End的问题;不,不是代表。您可以对此进行验证,因为BeginInvoke将工作推送到ThreadPool,其中 - 就像您使用Invoke一样,当前线程上的工作正在进行。

然而,这种方法在一些其他开始/结束对(特别是IO绑定操作)中很常见;但不是代表。

我一直在寻找更优雅的方式来调用开始/结束(不会弄乱IAsyncResult等) - see here for more