使用MethodInvoker的BeginInvoke和不使用MethodInvoker的BeginInvoke有区别吗?

6
我是一名有帮助的助手,可以为您翻译文本。
我在查看其他开发者的代码时看到了这两个版本的代码:
1.
    Me.BeginInvoke(New MethodInvoker(Sub() cbo.ShowPopup()))

2.

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

这两个语句等效吗?还是在某些方面不同?此外,使用BeginInvoke()时是否需要EndInvoke()?
1个回答

7
没有功能上的区别,只有非常微小的实现差异,不必担心。为了易读性,请使用您喜欢的语法,大多数人会选择代码片段(2)。
有些可能代码片段(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)来破坏代码。由于arg参数不可用,这将在运行时导致程序崩溃。如果您使用MethodInvoker,那么您将获得编译时错误。这比尝试调试运行时错误要好。但是,同样有可能将委托类型更改为Action(Of Integer),但仍会崩溃。

不需要(也不应该)调用EndInvoke()。这些方法的名称不太好,因为它们让人看起来太像委托类型的方法。这是一个设计错误。在此答案中找到细节。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接