0

私のプログラマーは、シリアルポートから高速データを取得し、タイマーが値を取得した後、タイマが無効になり、コードが以前にcomからlistviewに受け入れられた値を追加します。問題は、UIスレッドが完全にフリーズしていないのですが、フォームをドラッグすると遅くなってしまいます。サブタイトルのテキストを+1するたびに+1するコードはスムーズではありません。Timer1はUIスレッドをフリーズします

founditem.SubItems(4).Text = founditem.SubItems(4).Text + 1 

なぜとしては、タイマーは独自のスレッドをcreats知っている、それがUI(私はシリアルから正しいデータを受け入れるためにそのneccesary becsouse、タイマーを取り除くカント) 任意のヒントを凍結するべきではないということですか?私はinvoke、begininvokeとbackground_workerを試しましたが、正しくないかもしれません。 タイマーイベントからバックグラウンドワーカーに電話することはできますか?私はasycタスクがうまくいかない。私のコードは次のとおりです。

Private Sub spOpen() 
    Try 
     spClose() 
     spObj.PortName = "COM4" 
     spObj.BaudRate = 230400 
     spObj.Parity = IO.Ports.Parity.None 
     spObj.DataBits = 8 
     spObj.StopBits = IO.Ports.StopBits.One 
     spObj.Handshake = IO.Ports.Handshake.None 
     spObj.DtrEnable = False 'imp 
     spObj.RtsEnable = False 'imp 
     spObj.NewLine = vbCr 
     spObj.ReadTimeout = 0 
     spObj.WriteTimeout = 250 
     spObj.ReceivedBytesThreshold = 1 
     spObj.Open() 

    Catch ex As Exception 
     'catch 
    End Try 
End Sub 
Private Sub spClose() 
    Try 
     If spObj.IsOpen Then 
      spObj.Close() 
      spObj.Dispose() 
     End If 
    Catch ex As Exception 
     'handle the way you want 
    End Try 
End Sub 
Function ReverseString(ByVal sText As String) As String 
    Dim lenText As Long, lPos As Long 
    If Len(sText) = 0 Then Exit Function 
    lenText = Len(sText) 
    ReverseString = Space(lenText) 

    For lPos = lenText To 1 Step -2 
     If lPos > 0 Then Mid(ReverseString, lenText - lPos + 1, 2) = Mid(sText, lPos - 1, 2) 
     If lPos = 0 Then Mid(ReverseString, lenText - lPos + 1, 2) = Mid(sText, lPos, 2) 
    Next lPos 
    'Return 


End Function 

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick 
    'stop the timer (stops this function being called while it is still working 
    Timer1.Enabled = False 


    ' get any new data and add the the global variable receivedData 
    receivedData = ReceiveSerialData() 

    'If receivedData contains a "<" and a ">" then we have data 
    If ((receivedData.Contains("<") And receivedData.Contains(">"))) Then 
     'parseData() 
     first_msg = 1 

     parseData() 
    End If 

    ' restart the timer 
    Timer1.Enabled = True 
End Sub 
Function ReceiveSerialData() As String 
    Dim Incoming As String 
    Try 
     Incoming = spObj.ReadExisting() 
     If Incoming Is Nothing Then 
      Return "nothing" & vbCrLf 
     Else 
      Return Incoming 
     End If 
    Catch ex As TimeoutException 
     Return "Error: Serial Port read timed out." 
    End Try 
End Function 
Function parseData() 

    ' uses the global variable receivedData 
    Dim pos1 As Integer 
    Dim pos2 As Integer 
    Dim length As Integer 
    Dim newCommand As String 
    Dim done As Boolean = False 
    Dim count As Integer = 0 

    While (Not done) 

     pos1 = receivedData.IndexOf("<") + 1 
     pos2 = receivedData.IndexOf(">") + 1 

     'occasionally we may not get complete data and the end marker will be in front of the start marker 
     ' for exampe "55><T0056><" 
     ' if pos2 < pos1 then remove the first part of the string from receivedData 
     If (pos2 < pos1) Then 
      receivedData = Microsoft.VisualBasic.Mid(receivedData, pos2 + 1) 
      pos1 = receivedData.IndexOf("<") + 1 
      pos2 = receivedData.IndexOf(">") + 1 
     End If 

     If (pos1 = 0 Or pos2 = 0) Then 
      ' we do not have both start and end markers and we are done 
      done = True 

     Else 
      ' we have both start and end markers 

      length = pos2 - pos1 + 1 
      If (length > 0) Then 
       'remove the start and end markers from the command 
       newCommand = Mid(receivedData, pos1 + 1, length - 2) 

       ' show the command in the text box 
       RichTextBox1.Text = "" 
       RichTextBox1.AppendText(newCommand & vbCrLf) 

       'remove the command from receivedData 
       receivedData = Mid(receivedData, pos2 + 1) 
       'RichTextBox1.Text &= receivedData 


       uart_in = RichTextBox1.Text 
       data = "" 
       'RichTextBox2.Text = Mid(RichTextBox1.Text, 6, 3) 
       'If RichTextBox1.TextLength = 26 Then 

       can_id = Mid(uart_in, 6, 3) 'extracting and id 
       dlc = Mid(uart_in, 10, 1) 
       data = uart_in.Substring(26 - (dlc * 2)) 
       hex2ascii(data) 
       data = data.InsertEveryNthChar(" ", 2) 
       ' data = ReverseString(data) 
       Dim articlecheck As String = can_id 
       Dim founditem As ListViewItem = ListView1.FindItemWithText(articlecheck) 
       If Not (founditem Is Nothing) Then 
        founditem.SubItems(0).Text = can_id 
        founditem.SubItems(1).Text = dlc 
        ' If founditem.SubItems(2).Text <> data Then 
        ' founditem.SubItems(2).ForeColor = Color.LightYellow 
        founditem.SubItems(2).Text = data 
        ' End If 

        founditem.SubItems(3).Text = timer_count - founditem.SubItems(3).Text 
        founditem.SubItems(4).Text = founditem.SubItems(4).Text + 1 
        founditem.SubItems(5).Text = asciival 
        ' timer_count = 1 
        first_msg = 0 
       Else 
        Dim lvi As New ListViewItem(can_id) 
        lvi.SubItems.Add(dlc) 
        lvi.SubItems.Add(data) 
        lvi.SubItems.Add(timer_count) 
        lvi.SubItems.Add(count) 
        lvi.SubItems.Add(asciival) 
        ListView1.Items.Add(lvi) 

       End If 

      End If ' (length > 0) 

     End If '(pos1 = 0 Or pos2 = 0) 

    End While 

End Function 
Function hex2ascii(ByVal hextext As String) As String 
    Dim a As Integer 
    Dim y As Integer 
    Dim value As String 
    Dim num As String 


    For y = 1 To Len(hextext) Step 2 
     num = Mid(hextext, y, 2) 
     a = Val("&h" & num) 
     If a = 160 Or a = 0 Or a = 9 Or a = 32 Or a = 11 Then a = 46 
     value = value & Chr(a) 
    Next 
    asciival = value 

End Function 
+0

リッチテキストボックスにテキストを追加したまま、しばらくしてから何も削除しないと、非常に高価になります。 RTBは常に内部バッファを再割り当てし、既存のテキストをそのバッファにコピーする必要があります。 StringBuilderが文字列に役立つ理由は同じですRTBには何も似ていないので、古いテキストを確実に削除する必要があります。別のアイデアがどれ –

+0

Thxを、私はStringBuilderのでRTBを置き換えますbackgroundworkerなどを使ってみるのはどうですか? –

+0

新しいStringBuilderのget_buffer.Remove(0、get_buffer.Length) get_buffer.Append(newCommand&のvbCrLf) としてget_buffer薄暗いそれがパフォーマンスを少しimporvedが、それほどではない:返信用 –

答えて

-1
Dim System.Threading.Thread yourthread As New System.Threading.Thread(AddressOf yourfunction()) 
yourthread.Priority = System.Threading.Priority.Highest 
yourthread.Start(); 

あなたが関数内でループを作成し、それはタイマーのように動作させるために、ループの終わりにSystem.Threading.Thread.Sleep(1000)を追加することができます。タイマーさえあれば、このスレッドを通じて既存のすべての関数を呼び出すことができます。

スレッドを使用してコントロールにアクセスするときは注意してください。

Invoke(Sub() yourcontrol.property = someproperty) 
+0

本当にスレッドの優先順位を変更すべきではありません。 「通常の優先順位」スレッドはシステムによってスケジューリングされ、各スレッドにかなりのプロセッサ時間を与え、すべてのスレッドがスムーズに動作するようにします。優先度を高くすると、代わりに他のプロセスが枯渇する可能性があります。 –

+0

Afnan sry、私は –

+0

(AddressOf yourfunction())を(AddressOf parseData()) に変更して、自分のコードを実行しようとしました。 parseDataはあなたの関数であり、他のものではありません –

関連する問題