Этот быстрый совет стал длинным ответом. К сожалению.
Как отметил Тайлер в своем хорошем ответе, вызов Dispose()
- отличная практика программирования. Это связано с тем, что этот метод должен объединять все необходимое освобождение ресурсов, чтобы не было ненужных открытых ресурсов. Например, если вы записали какой-то текст в файл и не смогли закрыть файл (освободить ресурс), он останется открытым, и никто больше не сможет писать в него, пока GC не придет и не сделает то, что вы должны иметь. сделано.
Теперь в некоторых случаях будут "финализировать" методы, более специфичные для класса, с которым вы имеете дело, например, StreamWriter.Close()
, который переопределяет TextWriter.Close()
. Действительно, они обычно больше подходят для ситуации: например, Close()
StreamWriter сбрасывает поток и нижележащий кодер перед Dispose()
обработкой объекта! Круто!
Тем не менее, просматривая MSDN, вы обнаружите, что даже Microsoft иногда смущается множеством приближенных и распорядителей. На этой веб-странице , например, в некоторых примерах Close()
вызывается перед неявным Dispose()
(см. с использованием оператора , если вы не понимаете, почему он неявный), и в в частности, они не беспокоятся. С чего бы это? Я тоже был озадачен.
Причина, по которой я понял (и, подчеркиваю, это оригинальное исследование и я, безусловно, могу потерять репутацию, если я ошибаюсь), заключается в том, что Close()
может потерпеть неудачу, приводя к исключению, в то время как оставив ресурсы открытыми, в то время как Dispose()
наверняка освободит их . Вот почему a Dispose()
всегда должен охранять Close()
вызов (извините за каламбур).
MyResource r = new MyResource();
try {
r.Write(new Whatever());
r.Close()
finally {
r.Dispose();
}
И да, я думаю, Microsoft воспользовалась этим примером. Возможно, эта временная метка никогда не будет сброшена в файл.
Завтра я исправляю свой старый код.
Редактировать: извините, Браннон, я не могу прокомментировать ваш ответ, но вы уверены, что это хорошая идея - позвонить Close()
на finally
блок? Я предполагаю, что исключение из этого может разрушить остальную часть блока, который, вероятно, будет содержать важный код очистки.
Ответ Браннону: отлично, просто не забудьте позвонить Close()
, когда это действительно необходимо (например, при работе с потоками - мало что знаете о соединениях SQL в .NET).