【发布时间】:2012-10-12 11:44:06
【问题描述】:
委托中的 Invoke 和 DynamicInvoke 有什么区别?请给我一些代码示例来解释这两种方法之间的区别。
【问题讨论】:
-
如果您有多播委托(调用调用列表中包含的多个委托),则只有
.DynamicInvoke(args)可用。
标签: c# .net delegates invoke dynamic-invoke
委托中的 Invoke 和 DynamicInvoke 有什么区别?请给我一些代码示例来解释这两种方法之间的区别。
【问题讨论】:
.DynamicInvoke(args) 可用。
标签: c# .net delegates invoke dynamic-invoke
当你有一个委托实例时,你可能知道确切的类型,或者你可能只知道它是一个Delegate。如果您知道确切的类型,则可以使用Invoke,它非常快 - 一切都已预先验证。例如:
Func<int,int> twice = x => x * 2;
int i = 3;
int j = twice.Invoke(i);
// or just:
int j = twice(i);
但是!如果您只知道它是Delegate,它必须手动解析参数等 - 这可能涉及拆箱等 - 正在进行大量反思。例如:
Delegate slowTwice = twice; // this is still the same delegate instance
object[] args = { i };
object result = slowTwice.DynamicInvoke(args);
请注意,我已经写了args 长手,以明确涉及object[]。这里有很多额外的费用:
MethodInfo
基本上,尽可能避免DynamicInvoke。 Invoke 总是更可取,除非你只有一个 Delegate 和一个 object[]。
为了进行性能比较,在调试器(控制台 exe)之外的发布模式下打印以下内容:
Invoke: 19ms
DynamicInvoke: 3813ms
代码:
Func<int,int> twice = x => x * 2;
const int LOOP = 5000000; // 5M
var watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
twice.Invoke(3);
}
watch.Stop();
Console.WriteLine("Invoke: {0}ms", watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
twice.DynamicInvoke(3);
}
watch.Stop();
Console.WriteLine("DynamicInvoke: {0}ms", watch.ElapsedMilliseconds);
【讨论】:
Invoke: 0,0478ms, DynamicInvoke: 0,053ms 时。你为什么要比较他们超过 1 个电话?为什么第一个函数调用比第二个函数花费更长的时间?