2010-11-11 3 views
22

Класс StreamReader имеет метод close и dispose. Я хочу знать, какой метод вызывать для очистки всех ресурсов.закрыть или удалить

Если вы используете использование блока, я думаю, что он вызовет его метод dispose. Будет ли достаточно, чтобы очистить все ресурсы.

+1

http://stackoverflow.com/q/61092/102112 – Alex

ответ

22

Блок using будет называть Dispose() экземпляром StreamReader. Вообще говоря, если тип IDisposable, вы должны поместить его в область using.

EDIT: Если вы посмотрите на Close() реализации StreamReader с помощью отражателя, вы увидите, что он звонит Dispose(true). Поэтому, если вы не используете область using, вызов Close() вручную будет таким же, как вызов Dispose() в этом конкретном случае.

protected override void Dispose(bool disposing) 
{ 
    try 
    { 
     if ((this.Closable && disposing) && (this.stream != null)) 
     { 
      this.stream.Close(); 
     } 
    } 
    finally 
    { 
     if (this.Closable && (this.stream != null)) 
     { 
      this.stream = null; 
      this.encoding = null; 
      this.decoder = null; 
      this.byteBuffer = null; 
      this.charBuffer = null; 
      this.charPos = 0; 
      this.charLen = 0; 
      base.Dispose(disposing); 
     } 
    } 
} 
+0

закрыть вызовы dispose (true), будет использовать блок также call dispose (true)? – user496949

+0

Yup, it will ... –

+0

Это объясняет, почему, если у вас есть код внутри 'using' с вызовом' Close() ', то при запуске Visual Studio Code Analysis вы получите' CA2202 \t Не уничтожайте объекты несколько раз ' - потому что 'Close()' уже располагает, а 'using' в конечном итоге попытается удалить объект снова. Интересно, тогда ... почему мы действительно не сталкиваемся с 'System.ObjectDisposedException'. – Veverke

1

Используемый блок - это все, что вам нужно.

+0

Использование будет гарантировать, что вызов будет отправлен. Это похоже на вызов? – user496949

+0

dispose будет неявным закрыть поток –

16

Утилизировать достаточно и необходимо, так как он будет называть Close all самостоятельно и выполнять больше вещей, которые Close не будет делать.

Использование блока - это элегантный способ распоряжаться, поэтому да, используйте его, когда это возможно.

+0

Не так ли, наоборот. закрыть вызовет dispose? –

+0

@Backwards_Dave no, это будет серьезной ошибкой для объекта, который будет располагать себя. Возможно, вы захотите использовать экземпляр после его закрытия. –

+3

В классе TextReader (родительском потоке StreamReader) реализация методов 'Close()' и 'Dispose()' идентична и вызывает 'Dispose (true)'. В классе StreamReader 'Close()' вызывает переопределенный 'Dispose (true)', который предоставляет объект. Поэтому в этом случае правильно сказать, что 'Close' вызывает' Dispose'. –

0

Если вы хотите получить дополнительную информацию о using, посмотрите здесь

Using

Цитата с сайта:

используя оператор позволяет программисту указать, когда объекты что использование ресурсов должно выпускать . Объект, предоставленный оператору , должен реализовывать интерфейс ID-интерфейса . Этот интерфейс предоставляет метод Dispose, который должен освобождать ресурсы объекта.

0

Существует, по-видимому, некоторая озабоченность по поводу того, действительно ли выполняет свою работу Dispose.

По существу - вы можете быть достаточно уверены, что все в BCL (Библиотека базовых классов), который реализует IDisposable будет привести в порядок себя правильно, когда отчуждать называется - например, когда с помощью оператор выходит из области видимости.

Если возникли проблемы с закрытыми потоками, они бы были подобраны к настоящему времени - вы можете доверять IDisposable. Это когда вы используете другие библиотеки, которые вы полагаетесь на реализацию Dispose.

1

Используйте Dispose с помощью блока, чтобы гарантировать, что происходит очистка.

Используйте Close, если вы закончите с объектом значительно до конца используемого блока, чтобы быть как можно более быстрым при выпуске любых ресурсов.

Эти два будут работать рука об руку, хотя последнее может быть избыточным, если вы все равно достигнете конца блока за несколько наносекунд.

3

Мы все знаем, что System.IO.StreamReader не единственный класс .NET 4.0+, который реализует IDisposable и метод Close(). В случае с StreamReader в этом вопросе исходный код показывает, что базовый класс TextReader.Close(), TextReader.Dispose() оба запускают одни и те же строки кода. Вы также можете увидеть в коде, что TextReader.Dispose() - это реализация, когда вы вызываете StreamReader.Dispose() (потому что StreamReader не переопределяет эту сигнатуру перегрузки метода Dispose).

Так вызов StreamReader.Dispose() будет работать this inherited line of code, который вызывает защищенный метод переопределения StreamReader.Dispose(disposing: true) и так будет StreamReader.Close() вызов StreamReader.Dispose(disposing: true). Поэтому для случая StreamReader, Close() и Dispose() действительно выполняются те же строки кода.

Более общий, неклассовый ответ на вопрос Close() или Dispose()?, возможно, следует отметить, что у Microsoft достаточно ясный documentation on implementing IDisposable and the Dispose pattern. Быстрого чтения достаточно, чтобы показать вам, что внедрение метода Close() не является требованием шаблона Dispose.

imho причина нахождения метода Close() на стольких классах, которые реализуют IDisposable, является результатом соглашения, а не требований.

Кто-то заметил

Close and Dispose - which to call?

Примером другого класса, который реализует IDisposable с шаблоном Dispose, и имеет метод Close(). Выполняется ли Close() тем же самым кодом, что и Dispose()? Я не смотрел исходный код, но я бы сказал не обязательно.

Смежные вопросы