0

我一直在互联网上阅读如何解决从不同线程更新控件的问题,而不是包含控件的线程,还阅读了“Pro VB 2010 和 .Net 4.0 平台”,我开始怀疑。以下代码是否以同步方式执行?

Private Sub SaveData(ByVal filepath As String)
   If InvokeRequired Then
      Me.Invoke(New MethodInvoker(AddressOf SaveData))
   Else
      ... the actual code
   End If
End Sub
4

3 回答 3

0

这在很大程度上取决于您的调用上下文。

如果您从 UI 线程或主线程调用它,那么是的,它将同步运行。

如果您从不是您的 UI 或主线程的线程调用它,那么它将与您的 UI 或主线程异步运行,但与调用线程同步,等待 UI 或主线程完成处理委托。

所以它可以双向进行。它可以同步和异步操作。我认为您缺少的是代码本身不会以同步或异步方式执行,代码的执行是同步或异步的。

您制作更新功能的原因:

Private Sub UpdateLabel(byval tLabel as Label, byval Value as String)
    If tLabel.Invokerequired Then
         Me.Invoke(New MethodInvoker(AddressOf UpdateLabel)
    Else
        tLabel.Text = Value
    End If
End Sub

这样您就可以在想要更改文本时调用它,而不必担心跨线程异常。

在单击事件期间从 UI 线程调用此方法是安全的,从正在运行的后台线程调用也是安全的,因为更改仍只会在 UI 或主线程上进行。您使用这样的代码来确保与您对其他线程拥有的控件所做的更改保持同步。

这种更新方式旨在同步您的更改并避免交叉线程。

于 2013-02-15T19:38:09.197 回答
0

Invoke方法是一个同步调用,它将阻塞调用线程,直到委托在 UI 线程上完成执行。

如果要调用线程立即继续(在 UI 线程上的代码运行之前),调用BeginInvoke(),这是异步的。

于 2013-02-15T19:38:18.863 回答
0

我知道这个问题有点老了,但这是对 Pow-Ian 答案的修改,对我有用。

Private Sub UpdateLabel(ByVal tControl As Control, ByVal Value As String)
    If tControl.InvokeRequired Then
        tControl.Invoke(Sub() tControl.Text = Value)
    Else
        tControl.Text = Value
    End If
End Sub

这应该可以使用 UI 线程更改任何控件的文本,即使它是从异步方法调用的。

于 2019-12-04T00:56:16.037 回答