私のプログラマーは、シリアルポートから高速データを取得し、タイマーが値を取得した後、タイマが無効になり、コードが以前に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
リッチテキストボックスにテキストを追加したまま、しばらくしてから何も削除しないと、非常に高価になります。 RTBは常に内部バッファを再割り当てし、既存のテキストをそのバッファにコピーする必要があります。 StringBuilderが文字列に役立つ理由は同じですRTBには何も似ていないので、古いテキストを確実に削除する必要があります。別のアイデアがどれ –
Thxを、私はStringBuilderのでRTBを置き換えますbackgroundworkerなどを使ってみるのはどうですか? –
新しいStringBuilderのget_buffer.Remove(0、get_buffer.Length) get_buffer.Append(newCommand&のvbCrLf) としてget_buffer薄暗いそれがパフォーマンスを少しimporvedが、それほどではない:返信用 –