Preventing multiple deletion of objects

Consider the following code:

using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate)) { using (StreamWriter writer = new StreamWriter(stream)) { // Use the writer object... } } 

When a writer stream is available, it creates a FileStream stream inside.

Is there any other desgin for this other than the MSDN recommendation to handle the external usable stream in the finally clause:

 Stream stream = null; try { stream = new FileStream("file.txt", FileMode.OpenOrCreate); using (StreamWriter writer = new StreamWriter(stream)) { stream = null; // Use the writer object... } } finally { if(stream != null) stream.Dispose(); } 
+8
c # stream dispose msdn
source share
2 answers

This is a case where FxCop is very at odds with design choices in the .NET Framework. The problem is caused by StreamWriter, assuming ownership of the stream. In general, the design choice is โ€œdrop in successโ€, most programmers will assume that closing StreamWriter is sufficient to host the stream. In particular, when they use Close () instead of Dispose ().

Which works well in the vast majority of cases. In most cases, one specific use where this is very problematic is CryptoStream. A class that requires flushing and undetectable failures when the main thread is closed before the CryptoStream is flushed and deleted. A case where an FxCop warning would be appropriate, although it is too cryptic to easily recognize a specific problem;)

And the general case is when a programmer wrote his own Dispose () method and forgot to make it safe from being called more than once. This is what the FxCop warning warned is not smart enough to see that the Dispose method is actually safe.

In this particular case, the FxCop warning is simply useless. The entire .NET Framework is implemented as implementations of the Dispose () method. FxCop should automatically suppress these warnings for .NET platform code. But no, Microsoft also uses it. There are many [SuppressMessage] attributes in the source code of the .NET Framework.

Working around a warning is too ugly and error prone. And pointless, because nothing went wrong. Keep in mind that FxCop is just a diagnostic tool designed to generate the โ€œDid you read thisโ€ message. This is not a cop cop who is going to jail you when you ignore the rules. This is a compiler job.

Use the [SuppressMessage] attribute to disable the warning.

+3
source share

The solution for this particular case is to call the StreamWriter constructor overload, which allows you to tell it not to delete the underlying stream .

Unfortunately, this is only for .Net 4.5; otherwise you will have to do what you are already doing.

Also see this topic: Is there a way to close a StreamWriter without closing it with a BaseStream?

By the way, the code in OP does NOT throw an exception when you try!

The following example assumes that there is a folder named "C: \ TEST":

 using System; using System.IO; namespace Demo { public static class Program { public static void Main(string[] args) { // This does NOT cause any exceptions: using (Stream stream = new FileStream("c:\\test\\file.txt", FileMode.OpenOrCreate)) { using (StreamWriter writer = new StreamWriter(stream)) { writer.Write("TEST"); } } } } } 
+3
source share

All Articles