问题描述
委托中的 Invoke 和 DynamicInvoke 有什么区别?请给我一些代码示例来解释这两种方法之间的区别.
What is the difference between Invoke and DynamicInvoke in delegates? Please give me some code example which explain difference between that two methods.
推荐答案
当你有一个委托实例时,你可能知道确切的类型,或者你可能只知道它是一个 Delegate
.如果您知道确切的类型,则可以使用 Invoke
,它非常快 - 一切都已预先验证.例如:
When you have a delegate instance, you might know the exact type, or you might just know that it is a Delegate
. If you know the exact type, you can use Invoke
, which is very fast - everything is already pre-validated. For example:
Func<int,int> twice = x => x * 2;
int i = 3;
int j = twice.Invoke(i);
// or just:
int j = twice(i);
但是!如果你只知道它是 Delegate
,它必须手动解析参数等 - 这可能涉及拆箱等 - 很多反思正在进行.例如:
However! If you just know that it is Delegate
, it has to resolve the parameters etc manually - this might involve unboxing, etc - a lot of reflection is going on. For example:
Delegate slowTwice = twice; // this is still the same delegate instance
object[] args = { i };
object result = slowTwice.DynamicInvoke(args);
请注意,我写了 args
长手,以明确涉及到 object[]
.这里有很多额外的费用:
Note I've written the args
long hand to make it clear that an object[]
is involved. There are lots of extra costs here:
- 数组
- 验证传递的参数是否适合实际的
MethodInfo
- 根据需要拆箱等
- 反射调用
- 那么调用者需要做一些事情来处理返回值
基本上,尽可能避免 DynamicInvoke
.Invoke
总是更可取的,除非你只有一个 Delegate
和一个 object[]
.
Basically, avoid DynamicInvoke
when-ever you can. Invoke
is always preferable, unless all you have is a Delegate
and an object[]
.
为了进行性能比较,在调试器(控制台 exe)之外的发布模式下打印以下内容:
For a performance comparison, the following in release mode outside of the debugger (a console exe) prints:
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);
这篇关于调用和动态调用之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!