MemoryStream.Close() или MemoryStream.Dispose()

Кого я могу назвать?

Нужно ли звонить оба?

Будет ли другой выдавать исключение, если я уже вызвал один из них?

Ответ 1

Close() и Dispose() при вызове a MemoryStream выполняют только две вещи:

  • Отметьте объект, расположенный таким образом, чтобы случайное использование объекта в будущем вызывало исключение.
  • Возможно, 1 выслать ссылки на управляемые объекты, что может облегчить задачу GC в зависимости от реализации GC. (В отношении современных алгоритмов GC это не имеет никакого реального значения, так что это точка для академической дискуссии и не имеет существенного влияния на реальность.)

MemoryStream не имеет никаких неуправляемых ресурсов для утилизации, поэтому вам технически не нужно избавляться от него. Эффект не утилизации MemoryStream примерно такой же, как сброс ссылки на byte[] - GC очистит оба одинаковых способа.

Какую мне позвонить? Нужно ли звонить оба?

Метод потоков Dispose() делегировать непосредственно методу Close() 2 поэтому оба делают точно то же самое.

Будет ли другой выдавать исключение, если я уже вызвал один из них?

В документации для IDisposable.Dispose() указано, что безопасно вызывать Dispose() несколько раз, на любой объект 3. (Если это не так для конкретного класса, то этот класс реализует интерфейс IDisposable таким образом, который нарушает его контракт, и это будет ошибкой.)

Все, что сказать: на самом деле не имеет большого значения, размещаете ли вы MemoryStream или нет. Единственная реальная причина, по которой она имеет методы Close/Dispose, заключается в том, что она наследует от Stream, которая требует, чтобы эти методы как часть контракта поддерживали потоки, у которых есть неуправляемые ресурсы (такие как дескрипторы файлов или сокетов).


1Монообработка не освобождает ссылку byte[]. Я не знаю, реализует ли реализация Microsoft.

2 "Этот метод вызывает Close, который затем вызывает Stream.Dispose(Boolean)."

3 "Если объект Dispose method вызывается более одного раза, объект должен игнорировать все вызовы после первого."

Ответ 2

Используйте блок using, чтобы ваш объект был удален, если он реализует IDisposable interface

Ответ 3

Для этого можно использовать блок using. Он будет автоматически вызывать Dispose, когда он выходит за пределы его области.

Пример:

using (MemoryStream ms = new MemoryStream())
{
    // Do something with ms..
}
// ms is disposed here

Надеюсь, что это помогло.

Ответ 4

следующий код - Stream. Из отражателя, как вы можете видеть, вам не нужно закрывать, если вы распоряжаетесь (что подразумевается при использовании)

public void Dispose()
{
    this.Close();
}

Ответ 5

Кого я могу назвать?

Любое из них.

Нужно ли звонить оба?

Нет, одного достаточно.

Будет ли другой выдавать исключение, если я уже вызвал один из них?

Нет, одноразовый шаблон объявляет, что последующие вызовы Dispose не вызывают негативных эффектов.

Ответ 6

Вызов Close() будет внутренне вызывать Dispose(), чтобы освободить ресурсы.

См. эту ссылку для получения дополнительной информации: msdn

Ответ 7

Вызов только Dispose() сделает трюк =)

Ответ 8

В .NET 3.5 (не проверены другие версии) методы вызывается в следующем порядке при утилизации MemoryStream:

  • Stream.Dispose()
    • просто вызывает Close
  • Stream.Close()
    • вызывает Dispose (true), затем GC.SuppressFinalize(this)
  • MemoryStream.Dispose(истина)
    • устанавливает _isOpen, _writable и _expandable флаги в false
  • Stream.Dispose(истина)
    • закрывает событие async, если активен

Ответ 9

В качестве первого решения рекомендуется использовать операторы везде, где это возможно. Это описано здесь: http://msdn.microsoft.com/en-us/library/yh598w02.aspx

Когда время жизни объекта IDisposable ограничено одним методом, вы должны объявить и создать его экземпляр в операторе using. Оператор using вызывает метод Dispose для объекта правильным образом и (когда вы используете его, как показано ранее), он также заставляет сам объект выходить из области действия, как только вызывается Dispose. Внутри блока using объект доступен только для чтения и не может быть изменен или переназначен.

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

Есть исключения; например, System.Windows.Forms.Form и System.Data.SqlClient.SqlConnection имеют различное поведение для Close() и Dispose().

Для получения полной информации вы можете проверить здесь: https://blogs.msdn.microsoft.com/kimhamil/2008/03/15/the-often-non-difference-between-close-and-dispose/

Ответ 10

Ни один из вышеперечисленных. Вам не нужно звонить или Close или Dispose.

MemoryStream не содержит никаких неуправляемых ресурсов, поэтому единственный ресурс, который нужно восстановить - это память. Память будет возвращена во время сборки мусора с остальной частью объекта MemoryStream когда ваш код больше не ссылается на MemoryStream.

Если у вас есть долговременная ссылка на MemoryStream, вы можете установить для этой ссылки значение null, чтобы позволить MemoryStream собирать мусор. Close и Dispose освобождают ни паровой буфер, ни сам объект MemoryStream.

Поскольку ни Stream ни MemoryStream имеют финализатора, нет необходимости вызывать Close или Dispose чтобы вызывать GC.SuppressFinalize для оптимизации сборки мусора. Нет финализатора для подавления.