Я только что закончил читать "С# 4.0 в двух словах" (O'Reilly), и я думаю, что это отличная книга для программиста, желающего перейти на С#, но это оставило меня в недоумении. Моя проблема заключается в определении оператора using
. Согласно книге (стр. 138),
using (StreamReader reader = File.OpenText("file.txt")) {
...
}
точно эквивалентен:
StreamReader reader = File.OpenText("file.txt");
try {
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}
Предположим, однако, что это верно и этот код выполняется в отдельном потоке. Этот поток теперь прерывается с помощью thread.Abort()
, поэтому создается ThreadAbortException
, и пусть поток точно после инициализации читателя и перед вступлением в предложение try..finally
. Это будет означать, что читатель не настроен!
Возможное решение было бы следующим образом:
StreamReader reader = null;
try {
reader = File.OpenText("file.txt");
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}
Это будет безопасно.
Теперь для моих вопросов:
- Правильно ли авторы книги и оператор
using
не являются безопасными или ошибочны, и они ведут себя как в моем втором решении? - Если
using
эквивалентно первому варианту (не прерывается), почему он проверяет наличиеnull
вfinally
? - Согласно книге (стр. 856),
ThreadAbortException
можно выбросить в любом месте управляемого кода. Но, может быть, есть исключения, и первый вариант в любом случае прерван?
EDIT: Я знаю, что использование thread.Abort()
не считается хорошей практикой. Мой интерес является чисто теоретическим: как оператор using
ведет себя точно?