【发布时间】:2018-03-21 17:02:06
【问题描述】:
我正在做一个 TCP 连接客户端/服务器,我真的想在运行时更新标签或文本框,因为我正在使用一个工作正常的委托,但是当我尝试更新 Form1 时,它根本不像我一样工作喜欢。
在下面的代码中,我解释了我在做什么。
我有一个名为 Form1 的类:
Public Class Form1
Public server As tcp_server
Private Shared _instance As Form1 = Nothing
Public Shared ReadOnly Property MainInstance As Form1
Get
Return _instance
End Get
End Property
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Form1._instance Is Nothing Then
Form1._instance = Me 'Setting the main instance if none exists.
End If
server = New tcp_server("192.168.30.31", "5000")
server.connect()
End Sub
Delegate Sub SetTextCallback(ByVal textBox As TextBox, ByVal text As String)
Public Sub SetText(ByVal textBox As TextBox, ByVal text As String)
Try
If textBox.InvokeRequired Then
Dim d As SetTextCallback = New SetTextCallback(AddressOf SetText)
Me.Invoke(d, New Object() {textBox, text})
Else
textBox.AppendText(text)
'Me.ShowDialog()
Form1.MainInstance.Visible = False
Form1.MainInstance.ShowDialog()
End If
Catch ex As Exception
End Try
End Sub
End Class
错误发生在这里Form1.MainInstance.ShowDialog()
Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on.
还有其他类名为tcp_server 的方法:
Public Sub connect()
Try
Dim server_ipendpoint As New IPEndPoint(IPAddress.Parse(m_ip_host), m_port_host)
tcpLsn = New TcpListener(server_ipendpoint)
tcpLsn.Start()
tcpThd = New Thread(AddressOf waiting_client)
tcpThd.Start()
'Form1.Label2.Text = "Listening"
Form1.TextBox1.Text = "Listening" & vbCrLf
Catch ex As Exception
is_exception = True
End Try
End Sub
如您所见,在这种方法中,我开始监听传入的连接。
新线程被称为waiting_client
Private Sub waiting_client()
Try
Dim change_name_label As New Form1.SetTextCallback(AddressOf Form1.SetText)
change_name_label.Invoke(Form1.TextBox1, "helllllooooooooo")
Catch ex As Exception
End Try
End Sub
我无法在运行时更新TextBox1。该应用程序不会刷新 Windows 窗体。
我唯一拥有的就是这个,它正在做的事情:
Public Sub SetText(ByVal textBox As TextBox, ByVal text As String)
Try
If textBox.InvokeRequired Then
Dim d As SetTextCallback = New SetTextCallback(AddressOf SetText)
Me.Invoke(d, New Object() {textBox, text})
Else
textBox.AppendText(text)
Me.ShowDialog()
End If
Catch ex As Exception
End Try
End Sub
但这并不是真正想要的结果。
我要更新TextBox1,我的意思是改变Listening --> helllloooooo
我看了很多帖子都找不到解决办法。
所有 cmets 或想法将不胜感激。
谢谢。
【问题讨论】:
-
您无法通过其默认实例从后台线程访问表单。 Find out reason for form instancing 的可能重复项
-
我已经阅读了这篇文章,但它根本没有帮助我,我尝试做同样的事情但没有工作。感谢您的来信。
-
它绝对可以帮助你。在我的回答中,我描述了导致您的代码以当前方式运行的确切现象,即您无法通过后台线程中的默认实例访问
Form1(或任何其他形式)。你的问题真的没有其他答案。 -- 还请定义“不工作”。您在哪个部分遇到了问题? -
“默认实例”是指直接通过表单名称访问表单,而不必创建它的实例,例如
Dim newForm As New Form1。 VB.NET 是唯一一种允许您通过Form1直接访问它的语言(即您可以调用Form1.Show()而不是myForm.Show()),如果您不知道它们的具体行为方式,这实际上是一个相当大的问题.这里有很多关于 SO 的问题,根本原因只是缺乏关于默认实例如何工作的知识(因为很难知道,特别是因为它没有很好的文档记录)。 -
对不起,我在度假。我已经尝试了您在那篇文章中所说的所有内容,但是仍然出现相同的错误跨线程操作无效...。我无法在运行时更新 TextBox,我发现的唯一方法是我在帖子中确实提到过。我是这类问题的初学者,我没有找到其他解决方案。我真的很感激任何帮助或解决这个问题的方法。谢谢视觉文森特。
标签: vb.net tcp delegates thread-safety