Является ли метод утилизации вызываемым GC автоматически?
public void Method()
{
var disposable = new DisposableObject();
}
DisposableObject является IDisposable.
Является ли в этом случае метод Dispose будет вызываться автоматически GC?
3 ответа
Является ли в этом случае метод Dispose будет вызываться автоматически GC?
Нет, это не будет звонить Dispose
Вы должны назвать это сами или использовать using
блок, который обеспечит его утилизацию даже в случае исключения.
using(var disposable = new DisposableObject())
{
//your code
}
IDisposable
используется для обеспечения освобождения неуправляемых ресурсов, хранящихся в приложении, перед сборкой мусора. поскольку GC
не может освободить ресурсы, удерживаемые неуправляемыми ресурсами, такими как обработчик файлов.
Если класс переопределяет метод с именем Finalize
и экземпляр этого класса, как находят, был оставлен без GC.SuppressFinalize()
будучи вызванным для этого экземпляра, GC будет хранить ссылку на объект в списке вещей, чьи Finalize
следует запустить как можно скорее (временно воскресив его) и пометить объект так, чтобы в следующий раз, когда он был оставлен, он просто исчезал. Если какие-либо объекты были помещены в список для немедленного завершения, GC затем запустит поток для запуска их Finalize
методы.
По какой-то причине создатели C# решили немного запутать, запретив программистам переопределять Finalize
прямо и вместо этого требуется, чтобы программисты, желающие переопределить Finalize
используйте конструкцию, которую они называют "деструктором", с синтаксисом, напоминающим деструктор C++, но с совершенно другой семантикой. Хотя C# добавляет немного кода-обертки, обычно можно думать о ~className {whatever}
примерно эквивалентно переопределению Finalize
,
Microsoft рекомендует, если один переопределяет Finalize
(или реализует деструктор C#), этот переопределитель / деструктор должен просто вызывать метод с подписью void Dispose(bool)
, проходя False
для значения параметра. Это основано на том совете, что люди понимают, что GC призывает Dispose
, Обратите внимание, что сам GC не вызывает Dispose
; отметим далее, что большинство объектов не должны реализовывать деструкторы C# и не переопределять Finalize
любым другим способом. Если человек не понимает всех угловых случаев, связанных с Finalize
обычно лучше убедиться, что IDisposable.Dispose
вызывается до того, как объекты покинуты.
Нет, GC не вызывает Dispose для одноразовых объектов (объектов, реализующих IDisposable). GC управляет очисткой объекта, вызывая финализатор (деструктор) управляемых объектов. Вы реализуете метод Dispose, если вы хотите контролировать, когда освобождаются ресурсы управления (а не если они освобождены или нет).
Например, если у вас есть класс, имеющий член TCPClient, то это управляемый объект, который контролирует ресурс - порт, к которому он подключен. Если вы не реализуете IDispose в своем классе и используете его экземпляр, то в какой-то момент, когда GC увидит, что TCPClient больше не используется, он завершит этот объект, и порт будет закрыт - но вы не сможете контролировать WHEN, который будет бывает. Если вам нужен доступ к порту и определенное время, тогда вам нужно контролировать, когда он закрыт - в этом случае вы можете использовать IDispose и использовать оператор using или вызвать Dispose самостоятельно, чтобы убедиться, что ресурс (порт) освобожден.