委托中的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。Invoke总是可取的,除非您所拥有的都是a Delegate和an object[]。
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);