none
用serialport接收数据,需要update UI,除了用thread有没有方便点的方法?请指教 RRS feed

  • 问题

  • 程序如下:

        Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            recstr &= SerialPort1.ReadExisting

            'parse received message
            If Asc(Microsoft.VisualBasic.Left(recstr, 1)) = 65 And Len(recstr) = 40 Then      'check if the first byte of recstr is 65 and the length is 40
                'check crc
                If checkcrc(recstr) = True Then
                    'used to transfer msg to UI safely
                    recthread = New Thread(New ThreadStart(AddressOf ThreadSafe))
                    recthread.Start()
                Else
                    ToolStripStatusLabel2.Text = "comm error,failed crc"
                End If
            End If
        End Sub

    #Region "UI safe call,use thread & delegate"
        'used to transfer msg to UI safely
        Private recthread As Thread = Nothing

        Delegate Sub SetTextCallback(ByVal [text] As String)
        Delegate Sub addlistCallback(ByVal [text] As String)

        Private Sub ThreadSafe()
            updateui(recstr)
        End Sub

        Private Sub updateui(ByVal [text] As String)

    '每个控件都要写一段,由于UI上控件很多,写起来比较麻烦
            If lbldc_involt1.InvokeRequired Then
                Dim a As New addlistCallback(AddressOf updateui)
                Me.Invoke(a, New Object() {[text]})
            Else
                Qtemp = Val(Mid([text], 13, 1)) * 256
                Qtemp += Val(Mid([text], 14, 1))
                Rtemp = CInt(Qtemp / 16)
                lbldc_involt1.Text = Rtemp.ToString       

            End If

    '每个控件都要写一段,由于UI上控件很多,写起来比较麻烦
        End Sub
    #End Region
    End Class

    请高手指教。
    2008年7月23日 2:59

答案

  • 你好,我的意思是将需要更新的UI刷新一下,不用全部都刷新的。
    我觉得
    backgroundworker是一种比较好的方法,程序当中可以多创建一些线程这样有好处,否则线程太少程序响应会很慢很慢的。
    2008年7月29日 5:27

全部回复

  • 上面的代码不太对,重贴一下。

    Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            recstr &= SerialPort1.ReadExisting

            'parse received message
            If Asc(Microsoft.VisualBasic.Left(recstr, 1)) = 65 And Len(recstr) = 40 Then      'check if the first byte of recstr is 65 and the length is 40
                'check crc
                If checkcrc(recstr) = True Then
                    'used to transfer msg to UI safely
                    recthread = New Thread(New ThreadStart(AddressOf ThreadSafe))
                    recthread.Start()
                Else
                    ToolStripStatusLabel2.Text = "comm error,failed crc"
                End If
            End If
        End Sub

    #Region "UI safe call,use thread & delegate"
        'used to transfer msg to UI safely
        Private recthread As Thread = Nothing

        Delegate Sub updateuiCallback(ByVal [text] As String)

        Private Sub ThreadSafe()
            updateui(recstr)
        End Sub

        Private Sub updateui(ByVal [text] As String)
            Dim Qtemp As Byte
            Dim Rtemp As Single
            'dc volt 1
            If lbldc_involt1.InvokeRequired Then
                Dim a As New updateuiCallback(AddressOf updateui)
                lbldc_involt1.Invoke(a, New Object() {[text]})
            Else
                Qtemp = Asc(Mid([text], 13, 1)) * 256       'DC volt high
                Qtemp += Asc(Mid([text], 14, 1))            'DC volt low
                Rtemp = CSng(Qtemp / 16)
                lbldc_involt1.Text = Rtemp.ToString
            End If
        End Sub
    #End Region

     

    主要完成的是把serialport接收到的recstr在UI上显示,但是运行时出错了,

    运行到lbldc_involt1.Invoke(a, New Object() {[text]})

    提示出错,出错信息如下:

    System.OverflowException was unhandled
      Message="Arithmetic operation resulted in an overflow."
      Source="System.Windows.Forms"
      StackTrace:
           at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
           at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
           at Helios.mainfrm.updateui(String text) in C:\Documents and Settings\Andyren\Desktop\VB\Helios-V0.2\mainfrm.vb:line 553
           at Helios.mainfrm.ThreadSafe() in C:\Documents and Settings\Andyren\Desktop\VB\Helios-V0.2\mainfrm.vb:line 544
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.runTryCode(Object userData)
           at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()

    提高手请帮我看看,不胜感激。

    2008年7月23日 4:08
  • 出错的问题解决了。

    只是有没有其他简单的方法更新UI阿?

    2008年7月23日 6:09
  • 你好,更新UI的时候你最好在更改完数据以后,将UI里面的控件都刷新一下。

     

    2008年7月24日 3:36
  • 你是指只要将form刷新一下,还是将每个控件都刷一下?

    我现在用串口接收数据,然后用zedgraph画了12条动态变化的曲线,窗口响应已经很慢了,不知道用backgroundworker会不会好点?

    2008年7月27日 0:25
  • 你好,我的意思是将需要更新的UI刷新一下,不用全部都刷新的。
    我觉得
    backgroundworker是一种比较好的方法,程序当中可以多创建一些线程这样有好处,否则线程太少程序响应会很慢很慢的。
    2008年7月29日 5:27