【问题标题】:BeginInvoke with/without using MethodInvoker—does it make any difference?BeginInvoke 使用/不使用 MethodInvoker — 有什么不同吗?
【发布时间】:2017-01-03 07:59:36
【问题描述】:

我在查看其他一些开发人员的代码时看到了这两个版本的代码:

1.

    Me.BeginInvoke(New MethodInvoker(Sub() cbo.ShowPopup()))

2.

    Me.BeginInvoke(Sub()
                      cbo.ShowPopup()
                   End Sub)

这两个语句是等价的,还是在某些方面有所不同?另外,BeginInvoke() 不需要 EndInvoke() 吗?

【问题讨论】:

    标签: .net vb.net multithreading invoke begininvoke


    【解决方案1】:

    不,两者在功能上没有区别。只有非常细微的实现差异,无需担心。使用您喜欢的语法以提高可读性,大多数人都会喜欢 sn-p (2)。

    sn-p (1) 可能是由 C# 程序员编写的。 BeginInvoke 的第一个参数是System.Delegate,它是所有委托类型的基类。 C# 要求您使用特定的委托类型,因为它是一种非常强类型安全的语言。但是 VB.NET 以(几乎)是一种动态语言而闻名,并且没有提出相同的要求,即使 Option Strict On 生效。

    我建议您使用 ildasm.exe 实用程序来查看为这两个语句生成的代码。您会看到它们产生完全相同的代码。只有一个很小的区别:编译器使用不同的委托类型。必然如此,因为它没有 MethodInvoker 的特殊知识。该委托类型是从 lambda 表达式自动生成的,并且具有像 VB$AnonymousDelegate_0 这样的古怪名称。假设您始终使用 MethodInvoker 并且不使用 Ngen,那么 可能 会给即时编译器更多的工作要做。很难获得资格,也无法准确衡量。这只是一次性成本,无需担心。

    另一个细节是类型安全,这是 C# 所要求的。您可以通过使用 Sub(arg As Integer) 来故意破坏代码用于 lambda 表达式。由于 arg 参数不可用,这将使程序在运行时崩溃。如果你使用 MethodInvoker,那么你会得到一个编译时错误。这比尝试调试运行时错误要好。但是,您将委托类型更改为Action(Of Integer) 的可能性也一样,它仍然会崩溃。

    不,您不需要(也不应该)调用 EndInvoke()。这些方法没有很好的名称,因为它使它们看起来太像委托类型的方法。这有点设计错误。在this answer 中查找细节。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-16
      • 2021-10-14
      • 1970-01-01
      • 2016-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多