【问题标题】:VB.NET Invoke MethodVB.NET 调用方法
【发布时间】:2013-07-18 07:52:15
【问题描述】:

我的代码中有这个方法:

Private Sub Display()
        Received.AppendText(" - " & RXArray)
End Sub

这两个调用有什么区别:

Me.Invoke(New MethodInvoker(AddressOf Display))

Display()

我知道这是关于线程的,但我不确定。

提前致谢

【问题讨论】:

  • 不同之处在于 Invoke() 大大增加了您的程序因死锁而挂起的几率。始终使用 BeginInvoke() 代替。 SerialPort 类尤其麻烦,您必须 在 DataReceived 事件处理程序中使用 BeginInvoke 类,因为它在工作线程上运行,因此无法直接更新控件。调用 SerialPort.Close() 方法时,使用 Invoke() 会导致死锁。

标签: vb.net multithreading delegates


【解决方案1】:

在不同线程中工作时使用Invoke 方式。例如,如果调用者与 GUI 不在同一个线程中。

如果调用者不需要等待方法的结果,你甚至可以使用BeginInvoke

GuiObject.BeginInvoke(New MethodInvoker(AddressOf Display))

或更短:

GuiObject.BeginInvoke(Sub() Display)

为了更便于编写,您可以将调用移到 Display 函数中:

Private Sub Display()
    If Me.InvokeRequired Then
        Me.Invoke(Sub() Display)
        Return
    End IF
    Received.AppendText(" - " & RXArray)
End Sub

这样调用者就不必知道他是否在同一个线程中。

【讨论】:

  • 就个人而言,我讨厌这种递归的使用——第一次阅读代码的人必须花费精力来理解为什么需要递归,并确保它不会导致 INFINITE环形。恕我直言,最好编写一个私有子 DisplayMustBeOnUIThread 来完成这项工作,然后编写一个包装子例程 Display 直接调用它或在需要时通过调用来调用它。 Private Sub Display()If Me.InvokeRequired Then Me.Invoke(Sub() DisplayMustBeOnUIThread) Else DisplayMustBeOnUIThread()End Sub
【解决方案2】:

other answer添加参数:

Private Sub Display(ByVal strParam As String)
    If Me.InvokeRequired Then
        Me.Invoke(Sub() Display(strParam))
        Return
    End IF
    Received.AppendText(" - " & RXArray)
End Sub

【讨论】:

    【解决方案3】:

    对于未来的读者,您还可以通过执行以下操作来更新您的 UI 对象

    Private Sub Display()
        If Me.InvokeRequired Then
            Me.Invoke(Sub()  Received.AppendText(" - " & RXArray))
            Return
        End IF
    
    End Sub
    

    【讨论】:

    • 如果不需要调用,那么您的代码根本不会更新 GUI。这是一个错误
    猜你喜欢
    • 1970-01-01
    • 2012-01-22
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-02
    相关资源
    最近更新 更多