由于某些原因,我的应用中的后台线程无法更改主表单上的任何标签,文本框值等。当线程没有执行任何操作时,没有编译错误。
以下是一些示例代码:
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
有人能让我知道我做错了吗?
答案 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元素。
规范解决方案如下:
在你的情况下:
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.