2009-08-03 29 views
3

我是正確的,你只需要使用()的最外層流,如果你正在做的如(),並與多個包裹處理流

MemoryStream mstr = new MemoryStream(); 

using(StreamWriter w = new StreamWriter(mstr)) { 
    .... 
} 

由於配置的StreamWriter的還應該配置/關閉底層流,就沒有必要做這個?

using(MemoryStream mstr = new MemoryStream()) 
using(StreamWriter w = new StreamWriter(mstr)) { 
    .... 
} 

(注意,這些只是一些例子,對如何處置包裹流,不找像剛纔使用的StringWriter等替代品)

+0

OhHai。我修復了你的不匹配的括號。 KThxBai。 – abelenky 2009-08-03 19:00:29

回答

7

我的經驗法則:如果實現IDisposable,處置。

雖然目前(也可能是永久),調用StreamWriter.Dispose()關閉底層的流,您未來可能使用的其他流派生類可能不會。另外,它似乎也不實際調用Dispose(),所以非MemoryStreams可能無法正確處理(儘管我現在無法想象任何會受此影響的)。

所以,雖然你可以只安全地處理StreamWriter,我發現它是一個更好的做法,總是儘可能使用一次性使用塊。

4

從反射器中查看StreamWriter.Dispose方法,它看起來像基礎流得到關閉,但不處置。我會把每個流放在一個「使用」塊中以明確處理它們。

+1

實際上,底層流上的.Close會調用this.Dispose(),因此會自行處置。 – 2009-08-03 18:56:16

+2

這就是今天的事情,斯坦。我不認爲這是合同的一部分。 – 2009-08-03 18:57:30

+0

@John:我只是從「查看Reflector」中說Close會調用Dispose。我不是說要使用它,我只是說反射器實際顯示的是什麼。 – 2009-08-03 18:59:36

0

這的確是一個更好的做法,只是一直用using塊。

「總是」,除了一個衆所周知的WCF代理類的情況,其中一個設計缺陷有時可能會導致其Dispose方法拋出異常,失去原來的異常。

9

它是把所有相關的資源在自己的using塊從一個可讀性和可維護性來說不亞於任何一個好主意。例如在下面的代碼,最終梅開二度後,這是不可能的嘗試訪問mstr因爲它是很有效的塊中作用域:

using (MemoryStream mstr = new MemoryStream()) 
using (StreamWriter w = new StreamWriter(mstr) { 
    .... 
} 

// cannot attempt to access mstr here 

如果不這樣做的範圍是這樣的,那麼它仍然可以訪問mstr的地方它是有效的

MemoryStream mstr = new MemoryStream(); 
using (StreamWriter w = new StreamWriter(mstr) { 
    .... 
} 

mstr.Write(...); // KABOOM! ObjectDisposedException occurs here! 

因此,儘管它可能並不總是必要的(在這種情況下它不是)範圍之外這是一個好主意,因爲它既澄清和強制執行你的意圖爲到它的範圍。

3

爲了回答您的實際問題。 TextWriter的Dispose方法

public void Dispose() 
{ 
    this.Dispose(true); 
    GC.SuppressFinalize(this); 
} 

它調用受保護的Dispose並將true傳遞給它。從TextWriter.Dispose Method (Boolean)

當配置參數爲, 這種方法釋放任何託管對象,這 的TextWriter引用持有的所有資源 。該方法 調用每個 引用對象的Dispose方法。

然而,它是包裝在一個使用塊實現IDisposable的一切最好的做法,因爲我們不能保證被保護Dipose方法將總是與真正參數調用。