差异调用和DynamicInvoke之间(Difference Between Invoke and

2019-06-18 12:44发布

是什么在委托中调用和DynamicInvoke之间的区别? 请给我一些代码例子解释说,这两种方法之间的差异。

Answer 1:

当你有一个委托实例,你可能知道确切的类型,或者你可能只知道它是一个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);


文章来源: Difference Between Invoke and DynamicInvoke