I have a class, which raises an evert to the UI.
VB Code:
  1. Private Withevents _Conn As MyConnection
  2.  
  3. Private Sub _Conn_Data(ByVal Data As String) Handles _Conn.Data
  4.    Treeview1.Nodes.Add Data
  5. End Sub
the thing is that _conn calls another thread, which wiats for data. When data arrives the above event is raised, but .NET doesn't like adding the data to a treeview as the event has come from another thread.
To get this to work I must do:
VB Code:
  1. Private _Data As String
  2.  
  3. Private Sub _Conn_Data(ByVal Data As String) Handles _Conn.Data
  4.    _Data =  Data
  5.    Treeview1.Invoke(CType(AddressOf addnewnode, MethodInvoker))
  6. End Sub
  7.  
  8. Private Sub AddNewNode()
  9.    Treeview1.Nodes.Add _Data
  10. End Sub
this is not good.
What I would like is the event to be raised in the correct thread.
Someone mentioned that queues could be used.
The that I use is this:
VB Code:
  1. Imports System.Net.Sockets
  2. Imports System.IO
  3. Imports System.Text
  4.  
  5. Public Class TCPConnection
  6.  
  7.     Public Event DataArrived(ByVal Data() As Byte)
  8.     Public Event Disconnected()
  9.  
  10.     Private Const READ_BUFFER_SIZE As Integer = 255
  11.  
  12.     Private _ReadCallBack As AsyncCallback
  13.  
  14.     Private _HostAddress As String
  15.     Private _Port As Integer
  16.  
  17.     Private _TCPClient As TcpClient
  18.  
  19.     Private _NS As NetworkStream
  20.     Private _SW As StreamWriter
  21.     ' Private _SR As StreamReader
  22.  
  23.     Private _Buffer(READ_BUFFER_SIZE - 1) As Byte
  24.  
  25.     Public Sub New(ByVal HostAddress As String, ByVal Port As Integer)
  26.         _HostAddress = HostAddress
  27.         _Port = Port
  28.         Connect()
  29.     End Sub
  30.  
  31.     Public ReadOnly Property HostAddress() As String
  32.         Get
  33.             Return _HostAddress
  34.         End Get
  35.     End Property
  36.  
  37.     Public ReadOnly Property Port() As Integer
  38.         Get
  39.             Return _Port
  40.         End Get
  41.     End Property
  42.  
  43.     Public Sub Connect()
  44.         _TCPClient = New TcpClient(_HostAddress, _Port)
  45.         _NS = _TCPClient.GetStream()
  46.         '_SR = New StreamReader(_NS, Encoding.ASCII)
  47.         _SW = New StreamWriter(_NS, Encoding.ASCII)
  48.         _SW.AutoFlush = True
  49.         StartAsyncRead()
  50.     End Sub
  51.  
  52.     Public Sub Disconnect()
  53.         _TCPClient.Close()
  54.         _TCPClient = Nothing
  55.         RaiseEvent Disconnected()
  56.     End Sub
  57.  
  58.     Public Sub SendData(ByRef Data As String)
  59.         _SW.Write(Data)
  60.     End Sub
  61.  
  62.     Private Sub StartAsyncRead()
  63.         _ReadCallBack = New AsyncCallback(AddressOf DoRead)
  64.         _NS.BeginRead(_Buffer, 0, READ_BUFFER_SIZE, _ReadCallBack, Nothing)
  65.     End Sub
  66.  
  67.     Private Sub DoRead(ByVal Result As IAsyncResult)
  68.         Try
  69.             Dim BytesRead As Integer = _NS.EndRead(Result)
  70.  
  71.             If BytesRead < 1 Then
  72.                 Disconnect()
  73.             Else
  74.                 Dim Data(BytesRead - 1) As Byte
  75.  
  76.                 _Buffer.Copy(_Buffer, 0, Data, 0, BytesRead)
  77.                 RaiseEvent DataArrived(Data)
  78.                 StartAsyncRead()
  79.             End If
  80.         Catch e As Exception
  81.             Disconnect()
  82.         End Try
  83.     End Sub
  84. End Class
The function StartAsyncRead is the one that starts a new thread for receiving data.

Woka