委托中的Invoke和DynamicVoke有什么区别?请给我一些代码示例,解释这两种方法之间的区别.

推荐答案

当您有一个委托实例时,您可能知道确切的类型,或者您可能只知道它是Delegate.如果你知道确切的类型,你可以使用Invoke,也就是very fast——所有的东西都已经预先验证过了.例如:

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个参数
  • 根据需要取消装箱等
  • 反射调用
  • 然后调用方需要做一些事情来处理返回值

基本上,尽可能避免DynamicInvoke次.Invoke总是比较好的,除非你只有Delegateobject[].

为了进行性能比较,将在调试器(控制台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);

.net相关问答推荐

是否可以将 SandCastle 创建的两个页面合并到一个主页中?

将 BitmapImage 转换为 Bitmap,反之亦然

异步总是 WaitingForActivation

防止对话框在按钮的单击事件处理程序中关闭

如何在 C# 4.0 中使任务进入睡眠状态(或延迟)?

共享 AssemblyInfo 用于跨解决方案的统一版本控制

InternalsVisibleTo 属性不起作用

软件包版本始终为 1.0.0,带有 dotnet pack

如何制作通用类型转换函数

C#中的引用类型

Visual Studio 2017 和 2019 突出显示滚动条中所选单词的出现

如何在多个解决方案之间共享相同的 Resharper 设置,无需人工干预?

为什么 C# 不推断我的泛型类型?

在 C# 中,为什么不能将 List 对象存储在 List 变量中

log4net的正确使用方法(记录器命名)

如何将整个字符串与正则表达式匹配?

在 .Net 中调用 Web 服务时绕过无效的 SSL 证书错误

如何获取当前的 ProcessID?

如果选中,则更改列表框项的 WPF DataTemplate

.NET Remoting 真的被弃用了吗?