none
VB2005 Richtextbox 資料過多問題 RRS feed

  • 問題

  • 各位前輩

    請教一下  我使用Rs232通訊 並將收到的資料存放在Richtextbox內

    問題主要有兩個 以下是我的程式

    RS232 接收部分:

     

    Private Sub myRS232_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles myRS232.DataReceived
        Dim DataReceived As String
    
        Tick = GetTickCount()
        UI_Str = ""
        Do
          On Error GoTo ERROR_PortOpen
          DataReceived = myRS232.ReadLine
          UI_Str &= Format_Sel(DataReceived)
        Loop
    
    ERROR_PortOpen: Console.WriteLine(GetTickCount() - Tick) UpdateUI_RTB(UI_Str, DataList) GC.Collect() End Sub
    Private Sub UpdateUI_RTB(ByVal newText As String, ByVal c As RichTextBox)
        If Me.InvokeRequired() Then
          Dim cb As New UpdateRTBUICallBack(AddressOf UpdateUI_RTB)
          Me.Invoke(cb, newText, c)
        Else
          c.SelectionStart = 2147483647
          c.SelectedText = newText
          c.ScrollToCaret()
        End If
    End Sub
    1 . 一個是當我Richtextbox內資料量很多時持續加入資料時畫面動作會變lag

    2.  當我每次加入的資料量很長時 速度也會很慢

    請問一下不知有沒什麼辦法可以解決這樣的問題

    請前輩們指教比較好的做法
    謝謝()

     

     

    2010年5月20日 上午 11:24

解答

  • 1.

    VB6 的 String 允許非 Unicode 的存在,因此隨時可以轉回 Byte() 再轉碼。

    VBNET 的 String 只允許 Unicode 的存在,預設是用 ASCII 轉換,若裡面有控制碼或超出 128 的字元,那就會造成掉碼。

     

    2.

    ReadLine 的要求是讀到 NewLine 為止,參考線上手冊:

    根據預設,ReadLine 方法會封鎖,直到收到該行為止。如果這不是您預期的行為,請將 ReadTimeout 屬性設定為零以外的任何值,強制 ReadLine 方法在通訊埠沒有可用的行時,擲回 TimeoutException

     

    封鎖部分:

    要是傳輸中發生亂碼或斷訊,你這程式就死了。

    例外部分:

    COM Port 通訊本來就不快,你的程式碼完全不考慮在 ReadLine 時,資料才傳回前幾個 bytes 而已嗎?

     

    前面這段就已經完全把我的意思說出來了:

    你先用除錯模式逐步執行,掛個 AccessPort 監聽收發資訊。

    還有 ReadLine 這類是最忌諱的,除非你能保證你呼叫這功能時,buffer 已經讀滿一行且超過,從你的程式碼看不出有這種檢查或保證,所以這裡就一定是用錯指令。

    你貼出來的程式碼中,並沒有看見跟時間有關的東西,對於 SerialPort / Socket 這類速度較差的,是滿明顯的邏輯錯誤。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    • 已標示為解答 Lolota Lee 2010年5月27日 上午 07:44
    2010年5月25日 下午 03:48

所有回覆

  • Hi!

    參考 http://www.dotblogs.com.tw/chou/archive/2009/04/12/7986.aspx#P012

    加上  Application.DoEvents() 看看


    歡迎參觀我的Blog.NET菜鳥自救會
    2010年5月20日 上午 11:37
    版主
  • 用 & 本來就會越來越慢。

    讓你的 Do Loop 內 Sleep(100) 以上,減少 & 運算次數及降低 CPU 需求好。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2010年5月20日 下午 12:42
  • 誠如心冷大所言, &來連接字串多了, 會越來越慢.

    其實你不一定要用Richtextbox的話, 用DataGridView或ListView這一類的也許會更順.

    http://www.dotblogs.com.tw/billchung/archive/2009/04/12/7981.aspx

    這邊有一個例子可以看


    以下是簽名檔, 請勿沒事對號入座
    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上
    2010年5月20日 下午 01:31
    版主
  • 感謝前輩們的建議

    我問題沒說的很清楚 抱歉

    我程式的目的是把命令跟通訊傳回的資料傳回的資料存進Richtextbox 如以下

    write data  crlf

    receive data 1 crlf

    receive data 2 crlf

    receive data 3 crlf

    因為我必須要在每條line內加入額外的資料 譬如 yy/mm/dd , receive data 3 crlf

    所以 我才使用readline

    UI_Str &= Format_Sel(DataReceived)

    我測試了一下

    serialport 的 DataReceived 的 ReceivedBytesThreshold 設定1

    他一次進來的資料量也不會很長

    所以UI_Str事實上並沒很多 我在 DataReceived內一開始就 UI_Str = ""

    接著我測試一下取消掉    UpdateUI_RTB(UI_Str, DataList) 這行

    連續執行一段時間也都沒問題 測試計算的時間也不會增長

    ERROR_PortOpen: Console.WriteLine(GetTickCount() - Tick)

    如果不取消那行 當連續時 richtextbox 資料越多時 就慢慢越來越慢

    當我固定時間下命令出去時 譬如100ms

    一開始沒問題  時間一久 richtextbox內可能護變成

    write data  crlf

    receive data 1 crlf

    receive data 2 crlf

    write data  crlf

    write data  crlf

    receive data 3 crlf

    receive data 1 crlf

    receive data 2 crlf

    所以我感覺很像是問題在richtextbox耶

    請各位大大指教一下  拜託拜託  謝謝 ^^

     

     

    2010年5月20日 下午 02:48
  • Hi,

    感覺問題在richtextbox的話

    可先用textbox替換測試看看


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2010年5月20日 下午 02:57
  • 當我固定時間下命令出去時 譬如100ms

    一開始沒問題  時間一久 richtextbox內可能護變成

    write data  crlf

    receive data 1 crlf

    receive data 2 crlf

    write data  crlf

    write data  crlf

    receive data 3 crlf

    receive data 1 crlf

    receive data 2 crlf

    所以我感覺很像是問題在richtextbox耶

    請各位大大指教一下  拜託拜託  謝謝 ^^

     

     

    你是用Timer每隔 100ms Send Command嗎 ?

    那的確有可能會造成順序的問題. 你可以看看下列文章的說明:

    http://www.dotblogs.com.tw/billchung/archive/2009/04/18/8044.aspx

     


    以下是簽名檔, 請勿沒事對號入座
    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上
    2010年5月20日 下午 04:00
    版主
  • RichTextBox 有其他問題,但問題不再你描述的地方。

    你先用除錯模式逐步執行,掛個 AccessPort 監聽收發資訊。

    還有 ReadLine 這類是最忌諱的,除非你能保證你呼叫這功能時,buffer 已經讀滿一行且超過,從你的程式碼看不出有這種檢查或保證,所以這裡就一定是用錯指令。

    你貼出來的程式碼中,並沒有看見跟時間有關的東西,對於 SerialPort / Socket 這類速度較差的,是滿明顯的邏輯錯誤。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2010年5月20日 下午 05:03
  • 謝謝各位前輩指導

    我程式的確是用Timer去做的

    這樣是造成順序錯誤的原因 邏輯錯誤 不好意思 ^^a

    我依照前輩們改的參考 修改了程式 並把通訊和RichTextbox分開測試

    通訊部分已經ok

    但RichTextBox 仍有些問題

    我在RichTextBox中設定follow 著form大小變化亦隨之變化

    當資料變多時  約12萬byte時 這時我改變form的大小(Resize) 卻lag的很嚴重(資料越大越慢)

    我停止將資料寫入RichTextBox 也是一樣的情況

    不知道有沒有什麼辦法可以解決這樣的問題

    請各位前輩指教一下

    謝謝~~

     

     

     

    2010年5月25日 上午 08:16
  • RichTextBox 有其他問題,但問題不再你描述的地方。

    你先用除錯模式逐步執行,掛個 AccessPort 監聽收發資訊。

    還有 ReadLine 這類是最忌諱的,除非你能保證你呼叫這功能時,buffer 已經讀滿一行且超過,從你的程式碼看不出有這種檢查或保證,所以這裡就一定是用錯指令。

    你貼出來的程式碼中,並沒有看見跟時間有關的東西,對於 SerialPort / Socket 這類速度較差的,是滿明顯的邏輯錯誤。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。

    謝謝心冷大指導

    這是我在VB6用的方法 測試一下似乎也可以用在NET上  只是不確定有沒有什麼問題 我已經改成TRY了 ^^

    On Error GoTo ERROR_PortOpen

    DataReceived = myRS232.ReadLine

    ....

    ....

    ERROR_PortOpen: Console.WriteLine(GetTickCount() - Tick)

    UpdateUI_RTB(UI_Str, DataList)

    GC.Collect()

     

    2010年5月25日 上午 08:19
  • 1.

    VB6 的 String 允許非 Unicode 的存在,因此隨時可以轉回 Byte() 再轉碼。

    VBNET 的 String 只允許 Unicode 的存在,預設是用 ASCII 轉換,若裡面有控制碼或超出 128 的字元,那就會造成掉碼。

     

    2.

    ReadLine 的要求是讀到 NewLine 為止,參考線上手冊:

    根據預設,ReadLine 方法會封鎖,直到收到該行為止。如果這不是您預期的行為,請將 ReadTimeout 屬性設定為零以外的任何值,強制 ReadLine 方法在通訊埠沒有可用的行時,擲回 TimeoutException

     

    封鎖部分:

    要是傳輸中發生亂碼或斷訊,你這程式就死了。

    例外部分:

    COM Port 通訊本來就不快,你的程式碼完全不考慮在 ReadLine 時,資料才傳回前幾個 bytes 而已嗎?

     

    前面這段就已經完全把我的意思說出來了:

    你先用除錯模式逐步執行,掛個 AccessPort 監聽收發資訊。

    還有 ReadLine 這類是最忌諱的,除非你能保證你呼叫這功能時,buffer 已經讀滿一行且超過,從你的程式碼看不出有這種檢查或保證,所以這裡就一定是用錯指令。

    你貼出來的程式碼中,並沒有看見跟時間有關的東西,對於 SerialPort / Socket 這類速度較差的,是滿明顯的邏輯錯誤。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    • 已標示為解答 Lolota Lee 2010年5月27日 上午 07:44
    2010年5月25日 下午 03:48