多线程文本框创建到flowlayoutpanel [英] multithreading textbox creation to flowlayoutpanel
问题描述
我已经有了程序正常工作的基础(我在这里做了很多实验,因为这是我正在编写的第一个真实程序),并且我可以通过简单的按钮单击事件使一切正常运行.但是,我的问题是我需要在后台运行tcplisten.
通过一些研究,我发现我需要使用线程.都很好.
侦听线程根据需要工作.保持端口开放,接收数据,然后将其传递给我的texbox创建者.但是我无法让文本框真正进入flowlayoutpanel.
I''ve got the basis of the program working (I''m doing a lot of experimentation here as this is the first real program I''m writing) And I had everything working perfectly with simple button click events. But, my issue is I need to have a tcplisten running in the background.
I have found out through a little bit of research that I need to use threads. All good.
The listen thread works as required. Holds the port open, receives the data, passes that onto my texbox creator. But I can''t get the textbox to actually go onto the flowlayoutpanel.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
tcpthread = New System.Threading.Thread(AddressOf tcplisten.MyTcpListener.Main)
tcpthread.Start()
txtthread = New System.Threading.Thread(AddressOf txtboxcreate)
txtthread.Start()
textboxestime = New Dictionary(Of TextBox, Integer)
textboxestime.Add(Nothing, 0)
End Sub
Public Class tcplisten
Public Shared datastring As String
Public Shared received As Boolean
Class MyTcpListener
Public Shared Sub Main()
Dim lf As Decimal = 23
Dim server As TcpListener
Dim datastring As String = Nothing
server = Nothing
Try
'' Set the TcpListener on port 13000.
''Dim port As Int32 = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\Iain-KVS", "p1", Nothing)
'' Dim ipstring As String = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\Iain-KVS", "IP", Nothing)
Dim port As Int32 = 13000
Dim localaddr As IPAddress = IPAddress.Parse("127.0.0.1")
server = New TcpListener(localaddr, port)
'' Start listening for client requests.
server.Start()
'' server.AcceptSocket()
'' Buffer for reading data
Dim bytes(1024) As Byte
Dim data As String = Nothing
'' Enter the listening loop.
''While True
'' MsgBox("Waiting for a connection... ")
'' Perform a blocking call to accept requests.
'' You could also user server.AcceptSocket() here.
Dim client As TcpClient = server.AcceptTcpClient()
'' Get a stream object for reading and writing
Dim stream As NetworkStream = client.GetStream()
Dim i As Int32
'' Loop to receive all the data sent by the client.
i = stream.Read(bytes, 0, bytes.Length)
''While (i <> 0)
'' Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i)
''MsgBox(data)
'' Process the data sent by the client.
''data = data.ToUpper()
Dim msg As Byte() = System.Text.Encoding.ASCII.GetBytes(data)
'' Send back a response.
stream.Write(msg, 0, msg.Length)
'' MsgBox("Sent: {0}", data)
'' i = stream.Read(bytes, 0, bytes.Length)
tcplisten.datastring = (data)
client.Close()
received = True
Form1.txtboxcreate()
'' End While
'' Shutdown and end connection
Catch e As SocketException
Console.WriteLine("SocketException: {0}", e)
Finally
'' server.Stop()
End Try
End Sub ''Main
End Class ''MyTcpListener
End Class
Public Sub txtboxcreate()
Dim check As Boolean
check = tcplisten.received
If check = True Then
Dim name As String
Dim text As String
Dim counttotal As Integer
Dim count As Integer
Dim tb As New TextBox()
text = tcplisten.datastring
' set the textbox dimensions being created
name = ("TxtBox" & CStr(counttotal))
With tb
.Name = name
.Text = text
.Multiline = True
.Height = 150
.Width = 250
.ReadOnly = True
.ScrollBars = False
.MaxLength = 100
.Tag = 20
.BackColor = Color.Black
.ForeColor = Color.White
' move unused properties under here'
' tb.ScrollBars = ScrollBars.Both
' tb.MaxLength = 100
' tb.Height = 100
' tb.AutoSize = True
' add events to the textbox created
Me.FlowLayoutPanel1.Controls.Add(tb)
Form1.textboxestime.Add(tb, 0)
AddHandler tb.MouseClick, AddressOf Me.TextBox1_MouseClick
End With
count = (count + counttotal)
End If
End Sub
我可以看到它是从tcplistener传递到txtboxcreate的,没有任何问题,但似乎并没有将文本框添加到flowlayoutpanel.
I can see it being passed from the tcplistener through to txtboxcreate without an issue, but it just does not seem to be adding the textbox to the flowlayoutpanel.
推荐答案
总而言之,如果通常使用TcpListener
或服务器端的套接字编程,则几乎可以避免使用至少两个线程进行通信:一个线程用于接受连接服务器端的新客户端,另一个线程用于它们之间的通信.请查看我过去的答案以获取更多详细信息和一些想法:
套接字编程中的业余问题 [来自同一端口号的多个客户端 [ Control.Invoke()与Control.BeginInvoke() [ ^ ],
Treeview Scanner和MD5的问题 [如何获取keydown事件在vb.net中的不同线程上操作 [启用禁用+多线程后控件事件不会触发 [ ^ ].
—SA
First of all, if you use theTcpListener
, or socket programming on the server side in general, you hardly can avoid using at least two threads for communication: one for accepting new clients connecting your server side, and other thread for communication between them. Please see my past answers for further detail and some ideas:
an amateur question in socket programming[^],
Multple clients from same port Number[^].
Now, about the thread method you show. You cannot do such things.
You cannot call anything related to UI from non-UI thread. Instead, you need to use the methodInvoke
orBeginInvoke
ofSystem.Windows.Threading.Dispatcher
(for both Forms or WPF) orSystem.Windows.Forms.Control
(Forms only).
You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].
See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].
—SA
这篇关于多线程文本框创建到flowlayoutpanel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!