委托中的Invoke和DynamicInvoke有什么区别?请给我一些代码示例来解释这两种方法之间的区别。
答案 0 :(得分:189)
当您拥有委托实例时,您可能知道确切的类型,或者您可能只知道它是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);