Vb.net 从工作线程更新UI表单
我是VB.NET中多线程的新手,遇到了一个问题,我想从后台运行的服务线程将文本附加到表单上的文本框中 我正在开发的应用程序是一个客户机/服务器侦听器,我已经能够让客户机和服务器PC互相对话(通过MsgBox确认),但是我现在正在努力让服务器上的服务线程将文本附加到文本框中,没有任何可视的情况发生 我有一个名为testDebug的表单,它调用一个类(RemoteSupport),这个类执行所有握手任务,并用连接数据更新文本框 谁能确定我哪里出了问题,并为我指出正确的方向 以下是我的代码: 该表单有一个名为txtOutput的文本框,以下内容来自remoteSupport类Vb.net 从工作线程更新UI表单,vb.net,Vb.net,我是VB.NET中多线程的新手,遇到了一个问题,我想从后台运行的服务线程将文本附加到表单上的文本框中 我正在开发的应用程序是一个客户机/服务器侦听器,我已经能够让客户机和服务器PC互相对话(通过MsgBox确认),但是我现在正在努力让服务器上的服务线程将文本附加到文本框中,没有任何可视的情况发生 我有一个名为testDebug的表单,它调用一个类(RemoteSupport),这个类执行所有握手任务,并用连接数据更新文本框 谁能确定我哪里出了问题,并为我指出正确的方向 以下是我的代码: 该表单有
Dim outMessage As String = (encoder.GetString(message, 0, bytesRead))
MsgBox(outMessage, MsgBoxStyle.Information, "MEssage Received")
If outMessage IsNot Nothing Then
If testDebug.InvokeRequired Then
' have the UI thread call this method for us
testDebug.Invoke(New UpdateUIDelegate(AddressOf HandleClientComm), New Object() {outMessage}) '
Else
testDebug.txtOutput.AppendText(outMessage)
End If
'RaiseEvent MessageReceived(outMessage) // a previous attempt to use custom events
End If
Dim outMessage As String = (encoder.GetString(message, 0, bytesRead))
MsgBox(outMessage, MsgBoxStyle.Information, "MEssage Received")
If outMessage IsNot Nothing Then
If testDebug.InvokeRequired Then
' have the UI thread call this method for us
testDebug.Invoke(New MessageReceivedHandler(AddressOf Testdebug.Message_Received), New Object() {outMessage})
Else
testDebug.txtOutput.AppendText(outMessage)
End If
end if
我不确定invoke方法是否是理想的解决方案,或者自定义事件是否是理想的解决方案,我花了一些时间尝试让自定义事件工作,但这些也不起作用
// In the RemoteSupport class
Public Delegate Sub MessageReceivedHandler(ByVal message As String)
Public Shared Event MessageReceived As MessageReceivedHandler
// Located throughout the RemoteSupport class where debug information is required.
RaiseEvent MessageReceived(outMessage)
// Located in the code-behind of the form
Private Sub Message_Received(ByVal message As String)
testDebugOutput(message) // this is a function I have created
// to append the text to the text box
End Sub
提供的代码已被削减,因此,如果有任何其他内容,你想看到或任何问题,请让我知道
谢谢你的帮助
编辑:我已经上传了两个VB文件(表单和类)到我的网站上,如果有人能看一下,帮助我识别UI不更新的问题,我将不胜感激
我尝试了其他一些方法,但在工作线程启动后,似乎没有任何东西可以更新UI
格式:mulholland.it/testDebug.vb.txt
类:mulholland.it/remoteSupport.vb.txt
谢谢你的帮助
Matt委托方法可能是您想要的方式,但我看不到UpdateUIDelegate的声明 我相信您的代码应该是这样的(假设您对remotesupport类本地的testdebug表单有一个引用)
Dim outMessage As String = (encoder.GetString(message, 0, bytesRead))
MsgBox(outMessage, MsgBoxStyle.Information, "MEssage Received")
If outMessage IsNot Nothing Then
If testDebug.InvokeRequired Then
' have the UI thread call this method for us
testDebug.Invoke(New UpdateUIDelegate(AddressOf HandleClientComm), New Object() {outMessage}) '
Else
testDebug.txtOutput.AppendText(outMessage)
End If
'RaiseEvent MessageReceived(outMessage) // a previous attempt to use custom events
End If
Dim outMessage As String = (encoder.GetString(message, 0, bytesRead))
MsgBox(outMessage, MsgBoxStyle.Information, "MEssage Received")
If outMessage IsNot Nothing Then
If testDebug.InvokeRequired Then
' have the UI thread call this method for us
testDebug.Invoke(New MessageReceivedHandler(AddressOf Testdebug.Message_Received), New Object() {outMessage})
Else
testDebug.txtOutput.AppendText(outMessage)
End If
end if
我有一个名为testDebug的表单
If testDebug.InvokeRequired Then
这是VB.NET编程中的一个经典陷阱。在If语句上设置一个断点。注意它如何返回False,即使您知道代码正在另一个线程上运行
InvokeRequired是窗体的实例属性。但testDebug是一个类名,而不是对testDebug类型窗体实例的引用。在VB.NET中实现这一点让许多VB.NET程序员陷入了深深的麻烦。这是VB6遗留下来的一个错误。当您这样做时,它会完全崩溃并在您面前爆炸在线程中。您将获得该表单的一个新实例,而不是用户正在查看的实例。该实例不可见,因为它的Show()
从未被调用。否则,由于该线程未运行消息循环,该实例就死定了
我已经用推荐的修复方法回答了这个问题好几次了。我只是让您参考它们,而不是在这里重新讨论: