我编写了一个包含两种形式的程序
在FrmTreeView中,我有一个创建getData
对象的方法,并放入名为_MyPoolingThreads
的全局变量,该变量的类型为List(of getData)
。 _MyPoolingThreads
是一个可以从任何形式访问的全局变量。
在getData
类中,我使用了每秒滴答的线程计时器,并使用MODBUS RTU
协议从我的设备中获取数据。成功从设备中获取数据后,我需要在主表单FrmMain
上显示此数据。您能否建议我如何实现这一机制?
以下是FrmTreeView的代码:
Imports System.Threading
Imports WeifenLuo.WinFormsUI.Docking
Public Class frmTreeView
Inherits DockContent
Private Sub cmsConnectionStartPooling_Click(sender As Object, e As EventArgs) Handles cmsConnectionStartPooling.Click
Dim _node = _CheckConnectionNode(tvNodes.SelectedNode)
If Not IsNothing(_node) Then
Dim _threadObject = _GetDataObject(_node)
If IsNothing(_threadObject) Then
_threadObject = New getData(_node, tvNodes) 'Here getData Object is created and added to _MyPooligThreads
_MyPoolingThreads.Add(_threadObject)
_threadObject.StartPooling(True)
Else
_threadObject.StartPooling(True)
End If
End If
End Sub
End Class
以下是getData
类的代码:
Public Class getData
'Thread Timer
Private _ThreadTimer As Timer
Public Property _TimerStarted As Boolean
Public Sub New(ByRef connNode As ConnectionNode, ByRef tv As TreeView)
_Name = connNode.DataItem.id.ToString
_connectionNode = connNode
_tv = tv
Handle_ComPortEventDelegate = New Handle_ComPortEventSUB(AddressOf Handle_ComPortEvent)
Handle_PollEventDelegate = New Handle_PollEventSUB(AddressOf Handle_PollEvent)
End Sub
Private Function _InitMBControl() As Boolean
'Do init Stuff
End Function
Public Sub StartPooling(val As Nullable(Of Boolean))
If Not IsNothing(val) Then
If val Then
If IsNothing(_ThreadTimer) Then
If _InitMBControl() Then
_ThreadTimer = New Timer(New TimerCallback(AddressOf _GetData), Nothing, 0, Timeout.Infinite)
_TimerStarted = True
Else
_TimerStarted = False
End If
Else
_ThreadTimer.Change(_GetPollDelay, Timeout.Infinite)
_TimerStarted = True
End If
End If
Else
If _TimerStarted Then
_ThreadTimer.Change(_GetPollDelay, Timeout.Infinite)
Else
_tv.Invoke(Handle_ComPortEventDelegate, New Object() {New MyEventArgs With {.EvenyType = MyEnums.MyPrivateEvents.POOLING_STOPPED}})
End If
End If
End Sub
Private Sub _GetData(ByVal state As Object)
_ThreadTimer.Change(Timeout.Infinite, Timeout.Infinite)
Dim _dataTS As Date = Date.Now
Select Case _connectionNode.DataItem.conn_type
Case MyEnums.ConnectionType.MODBUS_RTU
If _connectionNode.Nodes.Count > 0 Then
Dim _nd As DeviceNode = CType(_connectionNode.Nodes(0), DeviceNode)
While _TimerStarted And Not IsNothing(_nd)
If Not _nd.DataItem.skip And _nd.TimeOutCount <= 3 Then
_GetModbusRTUData(_nd, _dataTS)
Else
_nd.SkipCount = _nd.SkipCount + 1
If _nd.SkipCount > _nd.TimeOutCount * 2 Then
_nd.SkipCount = 0
_nd.TimeOutCount = 0
End If
End If
If Not IsNothing(_nd.NextNode) Then
_nd = CType(_nd.NextNode, DeviceNode)
Else
_nd = Nothing
End If
End While
End If
Case MyEnums.ConnectionType.MODBUS_RTU_OVER_TCP
Case MyEnums.ConnectionType.MODBUS_TCP
End Select
StartPooling(Nothing)
End Sub
Private Sub _GetModbusRTUData(ByRef _var As DeviceNode, ByVal _ts As DateTime)
Dim _modbusData = New Short(_var.DataItem._GetQty) {}
_modbusRTUResult = _modbusRTU.ReadHoldingRegisters(CByte(_var.DataItem.modbus_id),
CUShort(_var.DataItem.modbus_start_address),
CUShort(_modbusData.Length - 1), _modbusData)
Select Case _modbusRTUResult
Case MBS.Result.SUCCESS
_tv.Invoke(Handle_PollEventDelegate, New Object() {New MyEventArgs With {.MyNode = _var,
.valueDate = _ts,
.EvenyType = MyEnums.MyPrivateEvents.DATA_RECEIVED}})
For Each chnl As ChannelNode In _var.Nodes
chnl.DataItem.DataVal = _GetChannelData(chnl, _modbusData)
_tv.Invoke(Handle_PollEventDelegate, New Object() {New MyEventArgs With {.MyNode = chnl,
.valueDate = _ts,
.EvenyType = MyEnums.MyPrivateEvents.CHANNEL_DATA_RECEIVED}})
**'I want to pass data received here to FrmMain**
Next
Case MBS.Result.RESPONSE_TIMEOUT
Case MBS.Result.WRITE
Case MBS.Result.ISCLOSED
End Select
End Sub
Private Function _GetChannelData(ByRef chnl As ChannelNode, ByRef _dt As Short()) As Decimal
'Do stuff here
End Function
Private Delegate Sub Handle_ComPortEventSUB(e As MyEventArgs)
Private Handle_ComPortEventDelegate As Handle_ComPortEventSUB
Private Sub Handle_ComPortEvent(e As MyEventArgs)
End Sub
Private Sub ClearPortAndTimerThread()
End Sub
Private Delegate Sub Handle_PollEventSUB(e As MyEventArgs)
Private Handle_PollEventDelegate As Handle_PollEventSUB
Private Sub Handle_PollEvent(e As MyEventArgs)
End Sub
End Class