2010-08-06 123 views
9

我正在寫一個很多很多格式化文本的日誌到.net窗體窗體應用程序中的文本框。向文本框寫入大量文本

一旦數據超過了幾個兆位,速度就會變慢。由於我追加字符串必須重新分配每一次?我只需要將該值設置爲文本框一次,但在我的代碼中,我做了數萬次的line+=data

有一個更快的方法來做到這一點?也許是不同的控制?有我可以使用的鏈接列表字符串類型嗎?

+6

爲什麼你不使用StringBuilder,而你正在連接,並且一旦你完成設置ToString到TextBox.Text? – 2010-08-06 20:40:32

+1

@Alfred:對你的建議看起來很小的變化是最有效的。其不同之處在於StringBuilder將用於累積文本,然後使用AppendText()將文本附加到TextBox,之後清除StringBuilder。 – 2010-08-07 15:10:38

回答

7

如果文本框是逐步添加的,比如日誌輸出,StringBuilder將不起作用。

但是,如果上述屬實,如果你的更新不夠頻繁,可能理應你緩存更新的一些數字,然後在一個步驟追加他們(而不是不斷追加)。這會爲你節省很多字符串重新分配,然後StringBuilder會有幫助。

注:

  1. 創建一個類範圍的StringBuilder成員(_sb)
  2. 啓動一個定時器(或使用計數器)
  3. 附加文本更新_sb
  4. 當計時器滴答聲或某些計數器達到復位並追加到 文本框
  5. 從#1重啓進程
+1

雖然你的答案是絕對相關的,但我認爲聲明*我只需要將該值設置爲文本框一次,但在我的代碼中,我正在執行line + = data數萬次。*表示它不會是回答他的具體問題。 – Marc 2010-08-06 21:09:34

+2

@馬克:事實上,保羅的答案非常好。一個線程鎖定SB,附加到它,解鎖。它做了很多次。 UI線程可以每秒輪詢一些次數,鎖定SB,獲取ToString並清除它。這樣,UI更新頻率完全獨立於級聯頻率。 – 2010-08-06 21:23:38

5

將您的字符串與StringBuilder一起構建,然後使用toString()將其轉換爲字符串,然後將其分配給文本框。

+2

也許StringBuffer是我從來沒有聽說過的類,但我認爲它更可能是你的意思StringBuilder – 2010-08-06 20:41:14

+0

錯誤的語言,'StringBuffer'是java。 =) – Marc 2010-08-06 20:42:03

+0

是的,你是對的,我會編輯答案。 – Frank 2010-08-06 20:49:48

6

還沒有人提到虛擬化,這實際上是爲海量數據提供可預測性能的唯一途徑。即使使用StringBuilder並將其轉換爲每半秒一個字符串將是非常一旦日誌變得足夠緩慢。通過數據虛擬化,您只需要在內存中保存必要的數據(即用戶可以看到的內容,或者在任何一邊可能會看到更多內容),而其餘內容則會存儲在磁盤上。隨着新數據的出現,舊數據會「滾出」內存。

爲了使TextBox出現好像它有很多在它的數據,你會告訴它一樣。當用戶滾動時,您可以使用來自底層源的相關數據(使用隨機文件訪問)替換緩衝區中的數據。所以你的UI將監視一個文件,而不是監聽日誌事件。

當然,這比單純使用StringBuilder的工作要多得多,但我認爲這值得一提,以防萬一。

+0

如果你仔細看看Paul Sasik的回答,包括我的評論,我想你會發現它不會因大字符串而減慢。這是因爲我們在寫入TextBox時仍然使用AppendText並繼續清理StringBuilder。 – 2010-08-07 12:49:41

+1

@Steven:但是'TextBox'仍然包含所有數據,因此您的數據可以獲得的大小仍然受到限制。虛擬化消除了這種情況,因爲它只是查看整個數據集的一個小窗口。你只受到磁盤空間的限制。 – 2010-08-07 15:03:16

+0

任何成本/收益分析必須包含成本。虛擬化的文本框不太有用,因爲你甚至不能做簡單的事情,比如Ctrl + A,Ctrl + C。虛擬化適用於連接到數據庫表的網格等情況。 – 2010-08-07 15:09:04