2012-08-14 30 views
0

所以從我所瞭解的string vs StringBuilder是字符串生成器將實際修改自己的實例,而字符串將只是一個新的。所以,如果我正確地理解了這一點,那麼通過對不斷變化的變量使用字符串方法,我基本上可以最終使用所有內存,直到計算機需要轉儲它以騰出空間。字符串生成器是正確的選擇嗎?

我在做什麼是使用事件處理程序來監視串行通信。我將接收數據並解析出來,並將其顯示在文本框中。事件處理程序使用字符串來完成此目前。關注更好的編程,而不是用完所有的內存,當我不需要時,我正試圖清理我的代碼。

我開始用字符串生成器進行編碼,並開始出現StringBuilder不包含.contains方法的構建錯誤。

基本上我很好奇,如果我應該離開它獨自一人?我應該採取不同的方式嗎?我有沒有正確的理解,string將不可避免地讓我內存不足?

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
{ 
    SerialPort sp = (SerialPort)sender; 

    string indata = sp.ReadExisting(); 
    rx.AppendText(Environment.NewLine + indata); 
    string dataCheck = indata.ToUpper(); 
    if (dataCheck.Contains("CONNECT") || indata.Contains("CONNECTED")) 
    { 
     cState.Text = "Connected"; 
     connectLink(); 
    } 
    if (dataCheck.Contains("NO CARRIER")) 
    { 
     cState.Text = "Disconnected"; 
     disconnect(); 
    } 
    dataCheck = null; 
} 
+3

對於與此類似的問題,[codereview.se]也是一個很好的地方...順便說一句,你可以擺脫'dataCheck = null;'賦值,因爲它沒有可測量的效果記憶。垃圾收集器最終會收集'dataCheck',不管你是否指定null。 – Adam 2012-08-14 00:22:49

+0

現在,你的代碼被徹底打破了,這個問題是無關緊要的。 ReadExisting()永遠不會給你一個字符串,如真實世界中的「CONNECT」。你只有在你調試你的代碼時纔會這樣做。在沒有調試器的情況下運行你的代碼時,最好你會得到「CO」。 – 2012-08-14 00:34:22

+0

'|| indata.Contains(「CONNECTED」)不需要,因爲搜索「CONNECT」將覆蓋這種情況。另外,你很可能想要搜索'dataCheck'。 – 2012-08-14 02:37:32

回答

5

你是錯的;使用字符串不會(通常)導致您用盡內存。

如果你正在做大量的串聯,使用字符串效率較低,因爲它需要建立一個新的字符串,並在每次連接時丟棄舊的字符串。
在這種情況下,您應該使用StringBuilder構建字符串,然後在需要顯示時調用ToString()

你的代碼不包含任何連接,所以使用StringBuilder不會有任何好處。

+3

*「你是不正確的;使用字符串不會導致你用完內存。」當然可以(理論上),但我不能說在這種情況下它是否是一個問題。我曾經必須解決許多大型字符串分配導致的OOM情況,這反過來又破壞了LOH,最終導致了OOM例外。 – 2012-08-14 00:20:56