Высвобождение ресурсов in.Net C#

Я новичок в C# и .NET, и читал об этом.

Мне нужно знать, почему и когда нужно освободить ресурсы? Разве мусорщик не заботится обо всем? Когда мне нужно реализовать IDisposable и чем он отличается от деструктора в C++?

кроме того, если моя программа довольно мала, то есть заставка, мне нужно заботиться о выпуске ресурсов?

спасибо.

6 ответов


в принципе, вам нужно беспокоиться о высвобождении ресурсов для неуправляемого кода - ничего за пределами .NET framework. Например, подключение к базе данных или файл в ОС.

сборщик мусора имеет дело с управляемым кодом-кодом в .NET framework.

даже маленькому приложению может потребоваться освободить неуправляемые ресурсы, например, он может записывать в локальный текстовый файл. Когда вы закончите с ресурсом, вам нужно убедиться, что метод Dispose объекта называемый. The используя оператор упрощает синтаксис:

using (TextWriter w = File.CreateText("test.txt"))
{
    w.WriteLine("Test Line 1");
}

объект TextWriter реализует интерфейс IDisposable, поэтому, как только блок using завершен, вызывается метод Dispose и объект может быть собран мусор. Фактическое время сбора не может быть гарантирована.

Если вы создаете свои собственные классы, которые необходимо правильно удалить, вам нужно будет реализовать интерфейс IDisposable и самостоятельно удалить шаблон. На простом приложение вам, вероятно, не нужно будет делать это, если вы делаете этой является хорошим ресурсом.


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

теперь сравните это с дескрипторами файлов. Операционная система может иметь достаточно места для выделения большего количества дескрипторов файлов , но если вы оставили дескриптор открытым для определенного файла, никто другой не сможет открыть файлы для написания. Вы следует сообщить системе, когда вы закончите с дескриптором-обычно закрывая соответствующий поток-как только вы закончите, и сделайте это таким образом, чтобы закрыть его, даже если возникает исключение. Обычно это делается с помощью using заявление, которое похоже на try / finally с вызовом Dispose в блоке finally.

деструкторы в C++ есть очень отличается от .NET-финализаторов, так как деструкторы c++ детерминированы - они автоматически вызываются, когда соответствующие например, переменная выпадает из области видимости. Финализаторы выполняются сборщиком мусора в какой-то момент после того, как объект больше не ссылается на какие-либо "живые" объекты, но сроки непредсказуемы. (В некоторых редких случаях, это может никогда.)

вы должны реализовать IDisposable себя, если у вас есть очистка, которая должна быть выполнена детерминированно-обычно это так, если одна из ваших переменных экземпляра и осуществляет IDisposable. В наши дни довольно редко требуется реализовать финализатор самостоятельно - обычно вам нужен только один, если у вас есть прямые удерживайте ручки операционной системы, обычно в виде IntPtr; SafeHandle делает все это намного проще и освобождает вас от необходимости писать финализатор самостоятельно.


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

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

public void Dispose()
protected void Dispose(bool disposing)

позволяет гарантировать, что неуправляемые ресурсы освобождаются ли Dispose способ или по завершению объекта.


вам не нужно освобождать память в управляемых объектах, таких как строки или массивы - это обрабатывается сборщиком мусора.

вы должны очистить ресурсы операционной системы и некоторые неуправляемые объекты, когда вы закончите их использовать. Если вы открываете файл, вы всегда должны помнить, чтобы закрыть этот файл, Когда вы закончите его использование. Если вы открываете файл исключительно и забываете закрыть, при следующей попытке открыть этот файл он может быть заблокирован. Если что-то реализует IDisposable, вы должны определенно рассмотреть, нужно ли вам закрыть его должным образом. Документация обычно скажет вам, что Dispose метод делает и когда он должен быть вызван.

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

также полезно знать о using заявление.


сборщик мусора освобождает память и очищает - через disposition - elemetns он удаляет. Но: он делает это только тогда, когда у него есть давление памяти.

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


вам нужно только беспокоиться о драгоценных ресурсах. Большинство объектов, создаваемых при программировании, не входят в эту категорию. Как вы сказали, сборщик мусора позаботится об этом.

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