.net - BeginInvoke 使用/不使用 MethodInvoker — 有什么不同吗?

标签 .net vb.net multithreading invoke begininvoke

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

1.

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

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

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

最佳答案

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

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

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

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

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

关于.net - BeginInvoke 使用/不使用 MethodInvoker — 有什么不同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41438861/

相关文章:

c# - 为什么要有一个非泛型的 IQueryable?

c# - 使用反射来获取对象属性的属性

vb.net - 声明全局、静态变量

c++ - 作为 OpenMP pragma 的结果的中间代码

VB.net、调用、委托(delegate)和线程。无法弄清楚如何跨类使用它们

.net - 无法对 .NET MAUI 类库进行单元测试

mysql - 无法通过 vb.net 验证 mysql

c# - Windows XP 中的重叠控件

java - 将 for 循环转换为多线程 block

c# - 为数据绑定(bind)的 datagridview 实现虚拟模式