基本上,我有一个服务器应用程序和相关的代理程序进程,用于将心跳数据传送到服务器。服务器应用程序实现TCP套接字类(TCPDevice),该类从WinForm调用。我知道从在不同线程上运行的进程更新UI的限制,并且实现这一点的首选技术是通过将Delegates与Invoke方法结合使用。以前很少需要使用Delegates(当然除了std windows事件和BackGroundWorker控件),我在如何在我的应用程序的上下文中做这件事感到茫然,并且会感谢一些帮助,尽管它有我发现我可以使用backgroundworker来编组UI的更新。
最终,应用程序需要通过来自已定义代理的提要更新设备网格,但是为了本练习的目的,只需更新UI上的状态栏就足够了。我认为与代码传播到表单相关的代码部分包含在OnDataReceived方法中。
以下是protoype应用程序的代码摘录,该应用程序应将上述内容放入适当的上下文中:
表单中的代码:
Private _device As TcpDevice
Private Sub btnListen_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnListen.Click
_device = New TcpDevice(uxIPaddress.Text, uxHost.Text, CInt(uxPort.Text))
_device.Listen()
Me.btnListen.Enabled = False
End Sub
来自TCPDevice类的代码
Public Class TcpDevice : Implements CNIMonitor.Core.Domain.IDevice
Private _ipAddress As String
Private _hostName As String
Private _port As Integer
Private _status As Integer
Private _previousStatus As Integer
Private _listener As TcpListener
Private _localAdd As System.Net.IPAddress
Private _activeConnection As TcpClient
Private _receiveBuffer(0) As Byte
Private _sendBuffer As Byte
Private _message As String
Private _dataRead As Integer 'The value returned from the getstream.endread method
Public Sub New(ByVal ipAddress As String, ByVal HostName As String, ByVal port As String)
_ipAddress = ipAddress
_hostName = HostName
_port = port
End Sub
Public Sub Connect() Implements CNIMonitor.Core.Domain.IDevice.Connect
End Sub
Public Sub Disconnect() Implements CNIMonitor.Core.Domain.IDevice.Disconnect
_activeConnection.Close()
_listener.Stop()
_activeConnection = Nothing
End Sub
Public Property HostName() As String Implements CNIMonitor.Core.Domain.IDevice.HostName
Get
HostName = _hostName
End Get
Set(ByVal value As String)
_hostName = value
End Set
End Property
Public Property IPAddress() As String Implements CNIMonitor.Core.Domain.IDevice.IPAddress
Get
IPAddress = _ipAddress
End Get
Set(ByVal value As String)
_ipAddress = value
End Set
End Property
Public Sub Listen() Implements CNIMonitor.Core.Domain.IDevice.Listen
Try
'Server component listens on the specified tcpip port
_localAdd = System.Net.IPAddress.Parse(_ipAddress)
_listener = New TcpListener(_localAdd, _port)
_listener.Start()
_listener.BeginAcceptTcpClient(AddressOf OnClientConnect, _listener)
'Update the status message
Debug.WriteLine("Listening for host " + _ipAddress + " on port " + _port.ToString + ".")
Catch ex As SocketException
Debug.WriteLine("Failed listening on " + _ipAddress + " over port " & vbCrLf & " .")
End Try
End Sub
Private Sub OnClientConnect(ByVal ar As IAsyncResult)
Debug.WriteLine("Received connection from " + ar.AsyncState.ToString)
'Get the connection object
_activeConnection = _listener.EndAcceptTcpClient(ar)
'on Client connect
Debug.WriteLine("Client" + _ipAddress + " connected over port " & vbCrLf & " ." & _port.ToString)
'Bind the event handler for dealing with incoming data
_activeConnection.GetStream.BeginRead(_receiveBuffer, 0, _receiveBuffer.Length, AddressOf onDataReceived, _
Nothing)
End Sub
Private Sub onDataReceived(ByVal ar As IAsyncResult)
Dim receiveLength As Integer = 0
ReDim _receiveBuffer(_activeConnection.ReceiveBufferSize - 1)
Try
Debug.WriteLine("Receiving from " + _ipAddress + ".")
' Complete the BeginReceive() asynchronous call by EndReceive() method
' which will return the number of bytes written to the stream
' by the client
receiveLength = _activeConnection.GetStream.EndRead(ar)
_message = Encoding.ASCII.GetString(_receiveBuffer, 0, receiveLength)
_activeConnection.GetStream.BeginRead(_receiveBuffer, 0, _receiveBuffer.Length, AddressOf onDataReceived, Nothing)
'NOW PASS THE INFORMATION RECEIVED BACK TO THE FORM
Catch
Debug.WriteLine("Transmission complete")
End Try
End Sub
Public Property Port() As Integer Implements CNIMonitor.Core.Domain.IDevice.Port
Get
Port = _port
End Get
Set(ByVal value As Integer)
_port = value
End Set
End Property
Public Property PreviousStatus() As Integer Implements CNIMonitor.Core.Domain.IDevice.PreviousStatus
Get
PreviousStatus = _previousStatus
End Get
Set(ByVal value As Integer)
_previousStatus = value
End Set
End Property
Public Property Status() As Integer Implements CNIMonitor.Core.Domain.IDevice.Status
Get
Status = _status
End Get
Set(ByVal value As Integer)
_status = value
End Set
End Property
End Class
答案 0 :(得分:0)
进行了一些进一步的调查,设法使代码工作。