vb.net - 后台线程问题

时间:2011-10-08 11:38:36

标签: vb.net multithreading backgroundworker

由于某些原因,我的应用中的后台线程无法更改主表单上的任何标签,文本框值等。当线程没有执行任何操作时,没有编译错误。

以下是一些示例代码:

Imports System.Threading

Public Class Class1
    Dim tmpThread As System.Threading.Thread

    Private Sub bgFindThread()
        Form1.lblStatus.Text = "test"
    End Sub

    Public Sub ThreadAction(ByVal Action As String)
        If Action = "Start" Then
            tmpThread = New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf bgFindThread))
            tmpThread.Start()
        ElseIf Action = "Abort" Then
            If tmpThread.IsAlive = True Then tmpThread.Abort()
        End If
    End Sub

End Class

有人能让我知道我做错了吗?

4 个答案:

答案 0 :(得分:0)

上面的AFAIK代码会抛出异常IllegalCrossThreadException,这是因为后台线程与UI线程不同,后台尝试在其他线程上设置值。所以Windows窗体检查每个正常工作的线程。 您可以将Control.CheckForIllegalCrossThreadCalls设置为false以使其正常工作。

以下代码是在未运行设置属性时

Add into your code
------------------------------
Delegate Sub MyDelegate()
Private Sub RunMyControl()
  lblStatus.Text = "test"
End Sub

Change your code
------------------------------
Private Sub bgFindThread
  lblStatus.BeginInvoke (New MyDelegate(AddressOf RunMyControl))
End Sub

该方法异步运行从后台线程到UI线程的代码。

答案 1 :(得分:0)

您只能从UI线程访问UI控件。

我建议先阅读此内容:http://www.albahari.com/threading/

答案 2 :(得分:0)

正如其他人所提到的,禁止(出于好的理由)从非UI线程更新UI元素。

规范解决方案如下:

  • 测试您是否在UI线程之外
  • 如果是,请求在UI线程内执行操作
  • [在UI线程内]更新控件。

在你的情况下:

Private Sub bgFindThread()
    If lblStatus.InvokeRequired Then
        lblStatus.Invoke(New Action(AddressOf bgFindThread))
        Return
    End If

    lblStatus.Text = "test"
End Sub

唯一改变的是方法开头的guard子句,它测试我们是否在UI线程内部,如果没有,则在UI线程中请求执行并返回。

答案 3 :(得分:0)

您可以使用委托更新后台线程中的UI控件。

实施例

Private Delegate Sub bkgChangeControl(ByVal bSucceed As Boolean)
Private dlgChangeControl As bkgChangeControl = AddressOf ChangeControl

Private Sub threadWorker_ChangeControl(ByVal bSucceed As Boolean)
    Me.Invoke(dlgChangeControl, New Object() {bSucceed})
End Sub  
     Private Sub ChangeControl()
     Me.lable="Changed"
     End Sub
      'In your background thread, call threadWorker_ChangeControl.