如何比使用DynamicInvoke更快地调用委托?

7

目前我使用DynamicInvoke,但速度非常慢。仍然使用Delegate类型,如何在不进行晚期绑定/使用DynamicInvoke的情况下直接调用Delegate

Delegate _method;    
_method.DynamicInvoke(_args);

谢谢。

请看类似问题的这个答案。 - adrianbanks
该帖子使用Action而不是Delegate。不确定为什么Delegate没有与Action相同的方法。 - DayTwo
发布真实的代码。不太清楚为什么需要使用委托而不是已声明的委托类型。 - Hans Passant
现在已经过了几年,但是你可以将 Delegate 强制转换为一个已声明的委托类型,前提是你预先知道参数和返回值类型。这通过在类型化的委托上使用 Invoke 方法来创建接近本地性能(在我的系统上比直接调用慢 5-10%)。 - Abel
2个回答

4
开源框架Impromptu-IntefaceDelegate添加了一个名为FastDynamicInvoke的扩展方法,它使用DLR而不是反射,运行速度比DynamicInvoke快20倍左右。
using ImpromptuInterface

...

_method.FastDynamicInvoke(_args);

这不就相当于调用((dynamic)_method)(_args)吗? - configurator
不行,除非 _method 的签名接受一个数组。 - jbtule
@jbtule 你有比较代码的例子吗?我今天尝试了一下,发现速度变慢了。 - Maya
@Maya 这是比较代码:http://code.google.com/p/impromptu-interface/source/browse/UnitTestImpromptuInterface/SpeedTest.cs#613 - jbtule
@jbtule 谢谢!实际上我已经看到它更快了,但无论如何还是感谢提供链接。如果您是这个库的开发者,也感谢您提供如此优秀的库。 - Maya

0

Invoke速度更快,但有点“隐藏”。来自Delegate类的MSDN

公共语言运行时为每个委托类型提供了一个Invoke方法,其签名与委托相同。您不必从C#、Visual Basic或Visual C++中显式调用此方法,因为编译器会自动调用它。 在反射中使用Invoke方法是很有用的,当您想要找到委托类型的签名时。

这意味着当您创建委托类型时,编译器会自动添加正确签名的Invoke成员。这允许直接调用而无需经过DynamicInvoke

在c#中,您可以像这样使用:

_method(_args);
//or
_method(typedArg1, typedArg2, andSoOn);

像调用普通方法一样调用它。这实际上调用了Invoke,对您来说应该更快。


哎呀,我无法将代码更改为_method(_args);。我收到了编译器错误“需要方法、委托或事件”。 - DayTwo
你的委托实际上只是一个“Delegate”吗?还是你为它使用了一个声明的签名? - Philip Rieck
1
这是一个 System.Delegate。谢谢。 - DayTwo
啊,抱歉 - 那就说得通了。如果您只使用 System.Delegate 作为委托类型,则不会生成任何 Invoke 方法。如果您可以创建特定的委托,则将看到巨大的速度提升。然而,仅使用 Delegate 是不可能的 - 每次调用都将是动态的。如果您确实需要走这条路,我建议查看 c# 4 和 dynamic 类型,因为 DLR 有一些速度提升。 - Philip Rieck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接