I've just finished reading "C# 4.0 in a Nutshell" (O'Reilly) and I think it's a great book for a programmer willing to switch to C#, but it left me wondering. My problem is the definition of using
statement. According to the book (p. 138),
using (StreamReader reader = File.OpenText("file.txt")) {
...
}
is precisely equivalent to:
StreamReader reader = File.OpenText("file.txt");
try {
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}
Suppose, however, that this is true and that this code is executed in a separate thread. This thread is now aborted with thread.Abort()
, so a ThreadAbortException
is thrown and suppose the thread is exactly after initializing the reader and before entering the try..finally
clause. This would mean that the reader is not disposed!
A possible solution would be to code this way:
StreamReader reader = null;
try {
reader = File.OpenText("file.txt");
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}
This would be abort-safe.
Now for my questions:
- Are authors of the book right and the
using
statement is not abort-safe or are they wrong and it behaves like in my second solution? - If
using
is equivalent to the first variant (not abort-safe), why does it check fornull
infinally
? - According to the book (p. 856),
ThreadAbortException
can be thrown anywhere in managed code. But maybe there are exceptions and the first variant is abort-safe after all?
EDIT: I know that using thread.Abort()
is not considered good practice. My interest is purely theoretical: how does the using
statement behave exactly?