1

如果我从非 UI 线程设置 Form 的 Text 属性,则需要使用 Invoke 来避免跨线程错误。但是,我可以在不使用 Invoke 的情况下读取 Text 属性。这安全吗?如果我尝试读取 Form 的 Handle 属性,则会出现跨线程错误。如果我阅读 Form 的 IsDisposed 属性,它可以正常工作。如何判断何时需要使用 Invoke?我是否应该一直使用 Invoke 来读取和写入属性值?

4

3 回答 3

4

每当您处于 UI 线程之外的线程中时,您应该Invoke在访问 UI 对象时使用。使用InvokeRequired属性来确定您是否实际上在不同的线程中。

于 2009-02-11T19:07:32.163 回答
1

最简单的方法是使用:

Delegate Sub SetTextCallback(ByVal [text] As String)

Private Sub SetText(ByVal [text] As String)
' InvokeRequired required compares the thread ID of the
' calling thread to the thread ID of the creating thread.
' If these threads are different, it returns true.
If Me.lboxResults.InvokeRequired Then
    Dim d As New SetTextCallback(AddressOf SetText)
    Me.Invoke(d, New Object() {[text]})
Else
    Me.lboxResults.Items.Add([text])
End If

结束子

对不起VB代码...

于 2009-02-11T19:08:51.957 回答
0

另一种选择是使用 SynchronizationContext。这不仅适用于 WinForms,也适用于 WPF 和 ASP.NET,并且它从 .NET 2.0 开始可用。

在主线程(例如在构造函数中)调用 SynchronizationContext.Current,并在需要同步调用时使用返回的对象。如果对象为空,则不需要同步。

于 2009-02-11T19:59:52.693 回答