委托(delegate)中的 Invoke 和 DynamicInvoke 有什么区别?请给我一些代码示例来解释这两种方法之间的区别。

最佳答案

当您有委托(delegate)实例时,您可能知道确切的类型,或者您可能只知道它是 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
  • 必要时拆箱等
  • 反射调用
  • 那么调用者需要做一些事情来处理返回值

  • 基本上,尽可能避免 DynamicInvokeInvoke 总是更可取的,除非你只有一个 Delegate 和一个 object[]

    为了进行性能比较,在调试器(控制台 exe)之外的 Release模式下打印以下内容:
    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);
    

    关于c# - Invoke 和 DynamicInvoke 之间的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12858340/

    10-14 20:57