我正在做一个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
我阅读了很多帖子,但找不到解决方案。
所有评论或想法我们将不胜感激。
感谢的。
答案 0 :(得分:0)
我不知道为什么你到处都在调用ShowDialog()
,但MainInstance
属性的目的是用{{替换每个 Form1
调用1}}。
特别是这条线导致错误:
Form1.MainInstance
因为它也需要改为:
change_name_label.Invoke(Form1.TextBox1, "helllllooooooooo")
此外,您不必真正创建上面使用的change_name_label.Invoke(Form1.MainInstance.TextBox1, "helllllooooooooo")
委托实例,您只需致电:
change_name_label
......这就足够了。 Form1.MainInstance.SetText(Form1.MainInstance.TextBox1, "helllllooooooooo")
方法已经为您完成剩下的工作。
现在,为了使您的代码正常工作,您需要做的最后一件事就是摆脱SetText()
调用。您还应该删除ShowDialog()
和Try/Catch
方法中的SetText()
,因为在任何地方添加空的方法都是不好的做法。如果您要将waiting_client()
置于可能发生错误的位置,则应通过记录或将其显示给用户(或两者)来正确处理。
<强> Form1中:强>
Try/Catch
(请注意,Private Delegate Sub SetTextCallback(ByVal textBox As TextBox, ByVal text As String)
Public Sub SetText(ByVal textBox As TextBox, ByVal text As String)
If textBox.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
textBox.Invoke(d, New Object() {textBox, text})
Else
textBox.AppendText(text)
End If
End Sub
可以缩短为Dim d As SetTextCallback = New SetTextCallback
)
<强> tcp_server:强>
Dim d As New SetTextCallback
现在你的代码应该正常工作了!