102
代表中的Invoke和DynamicInvoke之间有什么区别?请给我一些解释这两种方法之间差异的代码示例。Invoke和DynamicInvoke之间的区别
代表中的Invoke和DynamicInvoke之间有什么区别?请给我一些解释这两种方法之间差异的代码示例。Invoke和DynamicInvoke之间的区别
当你有一个委托实例时,你可能知道确切的类型,或者你可能只知道它是一个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
基本上,在y时应避免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);
这是否意味着在使用的DynamicInvoke的情况下,编译器生成更多的IL代码来处理委托调用? – testCoder
@testCoder不,它会使用反射 –
谢谢,非常全面的解释。 – testCoder