调用和动态调用之间的区别

4

本文介绍了调用和动态调用之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

委托中的 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);

这篇关于调用和动态调用之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

C# 中的多播委托奇怪行为?
Multicast delegate weird behavior in C#?(C# 中的多播委托奇怪行为?)...
2023-11-11 C#/.NET开发问题
6

参数计数与调用不匹配?
Parameter count mismatch with Invoke?(参数计数与调用不匹配?)...
2023-11-11 C#/.NET开发问题
26

如何将代表存储在列表中
How to store delegates in a List(如何将代表存储在列表中)...
2023-11-11 C#/.NET开发问题
6

代表如何工作(在后台)?
How delegates work (in the background)?(代表如何工作(在后台)?)...
2023-11-11 C#/.NET开发问题
5

没有 EndInvoke 的 C# 异步调用?
C# Asynchronous call without EndInvoke?(没有 EndInvoke 的 C# 异步调用?)...
2023-11-11 C#/.NET开发问题
2

Delegate.CreateDelegate() 和泛型:错误绑定到目标方法
Delegate.CreateDelegate() and generics: Error binding to target method(Delegate.CreateDelegate() 和泛型:错误绑定到目标方法)...
2023-11-11 C#/.NET开发问题
14