我一直在网上阅读如何解决从包含控件的线程更新控件的问题,并阅读“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
答案 0 :(得分: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或主线程上进行更改。您可以使用这样的代码来确保与其他线程拥有的控件的更改同步。
这种更新方式旨在同步您的更改并避免交叉线程。
答案 1 :(得分:0)
Invoke
方法是一个同步调用,它将阻止调用线程,直到委托在UI线程上完成执行。
如果要立即调用线程(在UI线程上的代码运行之前),请调用BeginInvoke()
,这是异步的。
答案 2 :(得分: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线程的任何控件的文本,即使从异步方法调用也是如此。