在委托中,Invoke 和 DynamicInvoke 有什么区别?请给我一些代码示例来解释这两种方法之间的区别。
当您有一个委托实例时,您可能知道确切的类型,或者您可能只知道它是一个 Delegate。如果你知道确切的类型,你可以使用 Invoke,这是 非常快-一切都已经预先验证。例如:
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[]参与。这里有很多额外的成本:
args
object[]
MethodInfo
基本上,尽可能避免 DynamicInvoke。除非你只有 Delegate和 object[],否则 Invoke总是更好。
DynamicInvoke
为了进行性能比较,将输出以下调试器(控制台 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);