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);