none
VB2010窗口假死问题(Timer定时器突然不工作) RRS feed

  • 问题

  • 我用VB.net作为上位机,PLC作为下位机进行通讯(modbus通讯协议)。VB.NET采集PLC的数据并存入数据库同时vb.net读取数据库中的数据在界面上显示波形曲线。

    主要思路:timer定时器定时读取数据库数据刷新波形曲线显示,并且发送命令给PLC进行通讯。PLC收到命令后通过serialport_datareceived事件返回我要的数据,在serialport_datareceived事件中通过serialport.read()读取串口数据,并且在serialport_datareceived事件中将数据存入数据库。

    timer_tick事件:读数据库->刷新波形曲线->刷新label->向PLC发送命令。

    serialport_datareceived事件:串口接收(serialport.read())->将数据存入数据库。

    另外:不通过串口收发来获取数据,单独用随机数产生数据并将数据存入数据库来显示波形,界面不会假死;

    单独用串口接收数据并存入数据库界面也不会假死;就是将以上两个功能组合起来就会出现假死现象。请高手们多指教,万分感谢!

      Private Sub TimerForCommunication_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerForCommunication.Tick
            RefreshScopeForChangeScale()'刷新界面波形显示区域
            ShowCurrentRecord()‘刷新界面标签
            Select Case ReadOrWrite
                Case 0 'read
                    MySerialPort.ReceivedBytesThreshold = 21
                    ReadPLC(&H1, &H3, &H0, &H2, &H0, &H8) '读PLC数据
                    Label1.Text = "读通讯中……"
                Case 1 'write
                    MySerialPort.ReceivedBytesThreshold = 8
                    WriteMultipe(&H1, &H10, &H0, &H32, &H0, &HF, &H1E, SendGroup) '向PLC写数据
                    Label1.Text = "写通讯中……"
            End Select
           
               End Sub

      Private Sub MySerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles MySerialPort.DataReceived
            Dim BoundRcvArray As Integer
            Dim CommunicationError As Boolean
             BoundRcvArray = MySerialPort.BytesToRead
            Dim RcvArray(BoundRcvArray - 1) As Byte
            MySerialPort.Read(RcvArray, 0, BoundRcvArray)
            Select Case ReadOrWrite
                 Case 0 '读
                    'CHECK回码的字节数
                    If BoundRcvArray <> 21 Then
                        'MessageBox.Show("读接收未完成")
                        CommunicationError = True
                    Else
                        'CHECK站号
                        If RcvArray(0) <> 1 Then
                            CommunicationError = True
                            'MessageBox.Show("返回站号错!")
                        End If
                        'CHECK功能码
                        If RcvArray(1) <> 3 Then
                            CommunicationError = True
                        End If
                        'CHECK接收字节数
                        If RcvArray(2) <> 16 Then
                            CommunicationError = True
                        End If
                        'CHECK CRC校验
                        If RcvArray(19) <> Modbus.CRC(RcvArray, 19)(0) _
                            Or RcvArray(20) <> Modbus.CRC(RcvArray, 19)(1) Then
                            CommunicationError = True
                        End If
                    End If
                    If CommunicationError = True Then
                        'MessageBox.Show("读回码出错!")
                        '如果通讯校验发现错误则丢弃数据重新发送命令
                        ReadOrWrite = 0
                    Else '通讯正常
                        '将数据写入数据库
                        Dim drNewRow As DataRow = TABLE1.NewRow()                    
                     drNewRow("CH1") = ((RcvArray(5) * 256 + RcvArray(6)) / 10).ToString
                        drNewRow("CH2") = ((RcvArray(7) * 256 + RcvArray(8)) / 10).ToString
                        drNewRow("CH3") = ((RcvArray(9) * 256 + RcvArray(10)) / 10).ToString
                        TABLE1.Rows.Add(drNewRow)
                        Try
                            m_daDataAdapter.Update(TABLE1)
                        Catch ex As Exception
                        End Try
                        ReadOrWrite = 0
                    End If
                Case 1 '写
                    'CHECK回码的字节数
                    If BoundRcvArray <> 8 Then
                        'MessageBox.Show("写接收未完成")
                        CommunicationError = True
                    End If
                    'CHECK站号
                    If RcvArray(0) <> 1 Then
                        CommunicationError = True
                    End If
                    'CHECK功能码
                    If RcvArray(1) <> 16 Then
                        CommunicationError = True
                    End If
                    'CHECK设置地址高
                    If RcvArray(2) <> 0 Then '要改
                        CommunicationError = True
                    End If
                    'CHECK设置地址低
                    If RcvArray(3) <> 50 Then '要改
                        CommunicationError = True
                    End If
                    'CHECK设置数量高
                    If RcvArray(4) <> 0 Then '要改
                        CommunicationError = True
                    End If
                    'CHECK设置数量低
                    If RcvArray(5) <> 15 Then '要改
                        CommunicationError = True
                    End If
                    'CHECK CRC校验
                    If RcvArray(6) <> Modbus.CRC(RcvArray, 6)(0) _
                        Or RcvArray(7) <> Modbus.CRC(RcvArray, 6)(1) Then
                        CommunicationError = True
                    End If
                    If CommunicationError = True Then
                        'MessageBox.Show("写回码出错!")
                        '如果通讯校验发现错误则丢弃数据重新发送命令
                        ReadOrWrite = 1
                    Else '通讯正常
                        ReadOrWrite = 0
                    End If
            End Select
                End Sub


    2012年9月4日 13:27

全部回复

  • 看起来像是在一边读数据库一边更新的时候出现了死锁,建议你在写数据库代码段加入断点调试一下看是否产生了死锁,如果是的话,请跳转到链接查看如何结束和处理死锁:http://msdn.microsoft.com/zh-cn/library/ms178104(v=sql.105)

    希望这些对你有帮助。

    Best regards,


    Shanks Zen
    MSDN Community Support | Feedback to us


    2012年9月5日 7:59
    版主
  • 怎么加入端点调试?您说的是断点吧?关键我现在的问题是刚开水运行的时候是正常的,运行个十多分钟就发现不和PLC通讯了,我估计是TIMER定时器不工作了,但是界面上的按钮还是能点的。而且发生这种情况的时间不一定,有的时候运行二十来分钟,有时候几分钟就有这种情况了。

    2012年9月6日 10:26