Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 从工作线程更新UI表单_Vb.net - Fatal编程技术网

Vb.net 从工作线程更新UI表单

Vb.net 从工作线程更新UI表单,vb.net,Vb.net,我是VB.NET中多线程的新手,遇到了一个问题,我想从后台运行的服务线程将文本附加到表单上的文本框中 我正在开发的应用程序是一个客户机/服务器侦听器,我已经能够让客户机和服务器PC互相对话(通过MsgBox确认),但是我现在正在努力让服务器上的服务线程将文本附加到文本框中,没有任何可视的情况发生 我有一个名为testDebug的表单,它调用一个类(RemoteSupport),这个类执行所有握手任务,并用连接数据更新文本框 谁能确定我哪里出了问题,并为我指出正确的方向 以下是我的代码: 该表单有

我是VB.NET中多线程的新手,遇到了一个问题,我想从后台运行的服务线程将文本附加到表单上的文本框中

我正在开发的应用程序是一个客户机/服务器侦听器,我已经能够让客户机和服务器PC互相对话(通过MsgBox确认),但是我现在正在努力让服务器上的服务线程将文本附加到文本框中,没有任何可视的情况发生

我有一个名为testDebug的表单,它调用一个类(RemoteSupport),这个类执行所有握手任务,并用连接数据更新文本框

谁能确定我哪里出了问题,并为我指出正确的方向

以下是我的代码: 该表单有一个名为txtOutput的文本框,以下内容来自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()
从未被调用。否则,由于该线程未运行消息循环,该实例就死定了

我已经用推荐的修复方法回答了这个问题好几次了。我只是让您参考它们,而不是在这里重新讨论:


不幸的是,这不起作用,它没有出错,但UI文本框没有更新。嗯,如果你仔细检查,它是否真的调用了委托,或者甚至没有到达委托行?不,它没有到达委托行。我已经放置了一个消息框来测试invokerrequired,它总是返回false。我已将两个文件上载到我的Web服务器,即类和表格代码,如果你想看一看,以获得一个完整的图片,这将是伟大的。我已经找到了一个帖子,这可能是我所追求的,但我不明白。有人可以解释给我,让我知道这是我应该做的:“解决方案是通过向名为parentForm的类引入新属性将父窗体传递给工作线程。然后,当从类实例化新对象时,我只需要将mainForm实例作为属性传递给它。然后我可以直接从类内调用父窗体”()你的链接帮助了我,在重新思考了我所采用的方法之后,我决定将第二个类放在第一个类中,并利用me.Control.Invoke,变得更简单,现在它可以工作了。谢谢你的帮助。Doh,完全错过了。我以前在这件事上绊倒了自己,只是在这里看了一下。谢谢你的帮助看守!