Я только что закончил читать "C # 4.0 в двух словах" (О'Рейли), и я думаю, что это отличная книга для программиста, желающего перейти на C #, но это заставило меня задуматься.Моя проблема заключается в определении оператора 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
может быть выброшеногде-нибудь в управляемом коде.Но, может быть, есть исключения, и первый вариант в конце концов безопасен при прерывании?
РЕДАКТИРОВАТЬ: Я знаю, что использование thread.Abort()
не считается хорошей практикой.Мой интерес чисто теоретический: как оператор using
ведет себя точно ?