Я прочитал MSDN и различные посты о шаблоне утилизации, но есть пара вещей, которые я не понимаю.Я написал следующий код для проверки шаблона утилизации.Обратите внимание, что нет неуправляемых ресурсов, я использую vs2008 и .net 3.5:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void tryDispose()
{
//test 1 : allocate resource and leave manage it to gc
BL.myclass df = new BL.myclass();
//test 2 : try to force garbage collecting
//GC.Collect();
//test 3 : call dispose myself
//using (BL.myclass df = new BL.myclass())
//{
//}
}
private void button1_Click(object sender, EventArgs e)
{
tryDispose();
}
это мой одноразовый класс:
class myclass: IDisposable
{
private StronglyTypedDs myDS;
private bool _disposed;
public myclass()
{
using (myDSTableAdapter docDocadpt = new myDSTableAdapter())
{
myDS = new StronglyTypedDs();
docDocadpt.Fill(myDS.TheTable);
}
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~myclass()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if (myDS != null)
myDS .Dispose();
myDS = null;
}
}
_disposed = true;
}
#endregion
}
Результаты:
test 1a - просто создавая экземпляр myclass, деструктор комментируется, так как myclass не содержит неуправляемых ресурсов: myclass.dispose не вызывается, даже если я закрываю приложение (вместо которого выполняется dispose).Каково состояние набора данных, когда я закрываю приложение?
test 1b - раскомментируйте деструктор, все в порядке, все утилиты вызываются, когда я закрываю приложение.
test 2a и 2b - я выполняю вышеуказанный тест, просто вызывая gc.collect: поведение идентичночтобы проверить 1a и 1b соответственно
тест 3 - все работает нормально (конечно)
во многих сообщениях говорится, что если myclass не содержит неуправляемые ресурсы, мне не нужно добавлятьдеструктор;Тем не менее, в моих тестах, если я не добавлю деструктор, myclass.dispose не будет вызван, когда я закрою приложение.Я не ждал, пока gc запустится сам (если я правильно помню, gc.collect не гарантирует освобождение экземпляра класса), чтобы проверить, вызовет ли он myclass.dispose.Итак, какова правильная реализация: всегда определять деструктор или избегать его, если myclass содержит только управляемые ресурсы?Если бы я заполнил все уровни поколений, мог бы gc с именем myclass избавиться или нет, не реализовав деструктор?
Наконец, я заметил, что если я определяю деструктор, но не объявляю класс как реализующий IDisposable, цепочка удаления работает в любом случае.Это может иметь смысл, поскольку деструктор может быть переведен для финализации в IL.Но я нахожу это действительно запутанным: это какая-то «неявная» реализация интерфейса, которую я не знаю?gc может распоряжаться предметом, но пользователи не могут
заранее поблагодарить
Стефано