[ Team LiB ] |
Recipe 3.29 Assuring an Object's DisposalProblemYou require a way to always have the Dispose method of an object called when that object's work is done or it goes out of scope. SolutionUse the using statement: using System; using System.IO; // ... using(FileStream FS = new FileStream("Test.txt", FileMode.Create)) { FS.WriteByte((byte)1); FS.WriteByte((byte)2); FS.WriteByte((byte)3); using(StreamWriter SW = new StreamWriter(FS)) { SW.WriteLine("some text."); } } DiscussionThe using statement is very easy to use and saves you the hassle of writing extra code. If the solution had not used the using statement, it would look like this: FileStream FS = new FileStream("Test.txt", FileMode.Create); try { FS.WriteByte((byte)1); FS.WriteByte((byte)2); FS.WriteByte((byte)3); StreamWriter SW = new StreamWriter(FS); try { SW.WriteLine("some text."); } finally { if (SW != null) { ((IDisposable)SW).Dispose( ); } } } finally { if (FS != null) { ((IDisposable)FS).Dispose( ); } } There are several points about the using statement.
This last point is described by the following code: FileStream FS; using(FS = new FileStream("Test.txt", FileMode.Create)) { FS.WriteByte((byte)1); FS.WriteByte((byte)2); FS.WriteByte((byte)3); using(StreamWriter SW = new StreamWriter(FS)) { SW.WriteLine("some text."); } } For this example code, we will not have a problem. But consider that the variable FS is usable outside of the using block. Essentially, we could revisit this code and modify it as follows: FileStream FS; using(FS = new FileStream("Test.txt", FileMode.Create)) { FS.WriteByte((byte)1); FS.WriteByte((byte)2); FS.WriteByte((byte)3); using(StreamWriter SW = new StreamWriter(FS)) { SW.WriteLine("some text."); } } FS.WriteByte((byte)4); This code compiles but throws an ObjectDisposedException on the last line of this code snippet because the Dispose method has already been called on the FS object. The object has not yet been collected at this point and still remains in memory in the disposed state. See AlsoSee Recipe 3.30 and Recipe 3.36; see the "IDispose Interface," "Using foreach with Collections," and "Implementing Finalize and Dispose to Clean Up Unmanaged Resources" topics in the MSDN documentation. |
[ Team LiB ] |