Invoke和DynamicInvoke之间的区别

代表中的Invoke和DynamicInvoke之间有什么区别? 请给我一些解释这两种方法之间差异的代码示例。

当你有一个委托实例,你可能知道确切的types,或者你可能只知道它是一个Delegate 。 如果你知道确切的types,你可以使用Invoke ,这是非常快的 – 一切都已经预先validation。 例如:

 Func<int,int> twice = x => x * 2; int i = 3; int j = twice.Invoke(i); // or just: int j = twice(i); 

然而! 如果你只是知道它是Delegate ,它必须手动parsing参数等 – 这可能涉及拆箱等 – 很多反思正在进行。 例如:

 Delegate slowTwice = twice; // this is still the same delegate instance object[] args = { i }; object result = slowTwice.DynamicInvoke(args); 

注意我已经写了很多args来清楚地说明一个object[]是涉及到的。 这里有很多额外的成本:

  • 数组
  • validation传递的参数对于实际的MethodInfo是“适合的”
  • 拆箱等必要的
  • reflection调用
  • 那么调用者需要做一些事情来处理返回值

基本上, DynamicInvoke避免DynamicInvokeInvoke总是可取的,除非你拥有一个Delegate和一个object[]

对于性能比较,在debugging器(控制台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);