Is it possible to create controls from a new thread in a multithreading windows form application
-
Hi Here is the code that I'm working on. Imports System.Threading Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click tcpSend = New TcpSender Dim trSend As New Thread(AddressOf tcpSend.RetrieveData) trSend.Name = "Data Receiver" tcpSend.Command = "Send data" tcpSend.SysName = "Cabin1" tcpSend.Port = 100 trSend.Start() End Sub Imports System.net Imports System.Net.Sockets Imports System.IO Public Class TcpSender Public Event SystemReplied(ByVal data As String) Public Command, SysName As String, Port As Int16 Public Sub RetrieveData() Try Dim tcpCli As New TcpClient(SysName, Port) Dim ns As NetworkStream = tcpCli.GetStream Dim sw As New StreamWriter(ns) Dim sr As New StreamReader(ns) ' Send data to the client. sw.WriteLine(Command) sw.Flush() ' Receive and display the response. If Command = "Send data" Then Dim strResult As String 'read the first line strResult = sr.ReadLine &am
-
Hi Here is the code that I'm working on. Imports System.Threading Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click tcpSend = New TcpSender Dim trSend As New Thread(AddressOf tcpSend.RetrieveData) trSend.Name = "Data Receiver" tcpSend.Command = "Send data" tcpSend.SysName = "Cabin1" tcpSend.Port = 100 trSend.Start() End Sub Imports System.net Imports System.Net.Sockets Imports System.IO Public Class TcpSender Public Event SystemReplied(ByVal data As String) Public Command, SysName As String, Port As Int16 Public Sub RetrieveData() Try Dim tcpCli As New TcpClient(SysName, Port) Dim ns As NetworkStream = tcpCli.GetStream Dim sw As New StreamWriter(ns) Dim sr As New StreamReader(ns) ' Send data to the client. sw.WriteLine(Command) sw.Flush() ' Receive and display the response. If Command = "Send data" Then Dim strResult As String 'read the first line strResult = sr.ReadLine &am
You must use Invoke to call a routine which will then be in the UI thread. For example:
Dim dataStorage As String Private Sub SystemRepliedEventHandler(ByVal data As String) Handles tcpSend.SystemReplied 'MsgBox(data) 'create the controls to display data 'this doesn't work 'Dim type As New TextBox 'type.Location = New Point(100, 100) 'type.Size = New Size(100, 100) 'type.Text = data 'Controls.Add(type) dataStorage = data Invoke(New MethodInvoker(AddressOf MyAddControl)) End Sub Private Sub MyAddControl() Dim type As New TextBox type.Location = New Point(100, 100) type.Size = New Size(100, 100) type.Text = dataStorage Controls.Add(type) End Sub
You can think of a more elegant way of passing over
data
and such, but basically this is what you need. It may be also interesting to consider theInvokeRequired
method, which will returntrue
if you are on a different thread than the UI. It can be useful when you need to know if you need to useInvoke
. In your case it's perfectly safe to always useInvoke
, but you can also change your code this way:Private Sub SystemRepliedEventHandler(ByVal data As String) Handles tcpSend.SystemReplied dataStorage = data If (InvokeRequired) Then Invoke(New MethodInvoker(AddressOf MyAddControl)) Else MyAddControl() End If End Sub
Hope this will be of help. :)
2+2=5 for very large amounts of 2 (always loved that one hehe!)
-
Hi Here is the code that I'm working on. Imports System.Threading Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click tcpSend = New TcpSender Dim trSend As New Thread(AddressOf tcpSend.RetrieveData) trSend.Name = "Data Receiver" tcpSend.Command = "Send data" tcpSend.SysName = "Cabin1" tcpSend.Port = 100 trSend.Start() End Sub Imports System.net Imports System.Net.Sockets Imports System.IO Public Class TcpSender Public Event SystemReplied(ByVal data As String) Public Command, SysName As String, Port As Int16 Public Sub RetrieveData() Try Dim tcpCli As New TcpClient(SysName, Port) Dim ns As NetworkStream = tcpCli.GetStream Dim sw As New StreamWriter(ns) Dim sr As New StreamReader(ns) ' Send data to the client. sw.WriteLine(Command) sw.Flush() ' Receive and display the response. If Command = "Send data" Then Dim strResult As String 'read the first line strResult = sr.ReadLine &am
You cannot create controls on a seperate thread. However, your thread code can Invoke a method on the UI thread that creates the controls for it.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007, 2008