在表单上,我想更新TextBox
。更新是从一个线程完成的。
线程就像那样启动:
ComThread = New Thread(AddressOf ComPlcVar.Scan_PLC)
ComThread.IsBackground = True
ComThread.SetApartmentState(ApartmentState.STA)
ComThread.Start()
Console.WriteLine("Do start thread")
更新功能是这样的:
If frmAcc.L_Cas_G.InvokeRequired Then
Dim d As New L_Cas_Trait_CallBack(AddressOf L_Cas_Trait)
frmAcc.L_Cas_G.Invoke(d, New Object() {Str})
Else
frmAcc.L_Cas_G.Text = Str & ControlChars.CrLf & " " & DateTime.Now.ToString("dd/MM/yyy") & " " & DateTime.Now.ToString("HH:mm:ss")
End if
声明函数的委托。
Public Delegate Sub L_Cas_Trait_CallBack(ByVal str As String)
Public Sub L_Cas_Trait(Str As String)
但是当我从线程调用更新函数时,我的UI未被更新。
它似乎只是一个用户界面问题,因为当我把写字符放在表格的texchanged方法上时,我得到了一个在控制台上显示正确字符串的事件......
Private Sub L_Cas_G_TextChanged(sender As Object, e As EventArgs) Handles L_Cas_G.TextChanged
Console.WriteLine(L_Cas_G.Text)
End Sub
有人知道我错过了什么吗?
谢谢。
答案 0 :(得分:0)
这可能是因为您在页面上的某些位置使用了交叉线程。请尝试使用AppendText。
这样的事情可能是:
Private Delegate Sub AppendTextBoxDelegate(ByVal TB As TextBox, ByVal txt As String)
Private Sub AppendTextBox(ByVal TB As TextBox, ByVal txt As String)
If TB.InvokeRequired Then
TB.Invoke(New AppendTextBoxDelegate(AddressOf AppendTextBox), New Object() {TB, txt})
Else
TB.AppendText(txt)
End If
End Sub
并按照以下方式使用:
AppendTextBox(YOURTEXTBOX, ADD YOUR CONTENT HERE)
答案来自:Update Text Box Properly when Cross-threading in Visual Basic (VS 2012 V11)
请查看页面上的完整示例。祝你好运。
答案 1 :(得分:0)
在我的测试中,我发现 invokerequiered 方法永远不会返回true。 我读到,当控件的句柄没有创建但是我用 IsHandleCreated 进行测试时它可能会发生并且看起来没问题。
由于我没有找到解决方案,我决定尝试另一种方法来更新tu UI。
所以我找到了 syncContext.Post 方法,它按预期工作。 我宣布:
Public syncContext As SynchronizationContext
在开始我的线程之前我做了:
syncContext = AsyncOperationManager.SynchronizationContext()
要更新我的文字(或标签):
syncContext.Post(New SendOrPostCallback(AddressOf UpdateStatus), Str_Tmp)
这个电话:
Private Sub UpdateStatus(ByVal State As Object)
frmAcc.L_Cas_G.Text = CType(State, String)
End Sub
现在可行。
感谢大家的帮助。