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避免DynamicInvoke 。 Invoke总是可取的,除非你拥有一个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);