Есть проблема с деструкторами и освобождением ресурсов.
Сборе мусор при закрытии програмы инициирует вызов деструкторов в непонятном (и неподходящем для меня) порядке. Тоесть, коллектор вызывает деструктор для тех обектов, на которые ещё живы референсы. Внизу маленький пример.
Существует множество класов Class1, Class2 и Class3. Class1 включает Class2 и Class2 включает Class3.Сначала вызывается деструктор для Class3, потом Class2 а потом уже для Class1, что не есть хорошо і не логично, потому что на обєкты Class2 и Class3 существуют референсы. В деструкторе Class1 будет сгенерировано исключение NullReference, потомучто, он вызовет MethodName() обекта m_Class2 у которого был уже вызван деструктор и поле m_FieldName ровно null.
Как обеснить такую ситуацию? Можно ли заставить GC роботать в правильном порядке (сначала Class1, потом Class2 и потом Class3) ?
public class Class1
{
private Class2 m_Class2;
public Class1() {
m_Class2 = new Class2();
}
public void MethodName() {
m_Class2.MethodName();
}
~Class1() {
m_Class2.MethodName();
m_Class2 = null;
}
}
public class Class2
{
private Class3 m_FieldName = new Class3();
public Class2() {
}
public void MethodName() {
m_FieldName.Field = 9;
}
~Class2() {
m_FieldName = null;
}
}
public class Class3
{
public int Field;
public Class3() {
}
~Class3() {
Field = 8;
}
}
Здравствуйте, Roter, Вы писали:
R>Есть проблема с деструкторами и освобождением ресурсов.
Начните с того, что деструкторов в .NET нет.
R>Сборе мусор при закрытии програмы инициирует вызов деструкторов в непонятном (и неподходящем для меня) порядке. Тоесть, коллектор вызывает деструктор для тех обектов, на которые ещё живы референсы.
Так и должно быть
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, Roter, Вы писали:
R>Есть проблема с деструкторами и освобождением ресурсов.
Тебе повезло и конкретно в твоем узком случае объекты образовали строго иерархическую структуру.
Однако, в общем случае, это совершенно не факт — объект Class3 может иметь внутри ссылку на Class1. Получили "кольцо".
Именно поэтому одновременно умирает все множество объектов, на которые нет внешних ссылок из живых. А уж в каком порядке у них вызовутся финализаторы — это непредсказуемо
С уважением, Евгений
JetBrains, Inc. "Develop with pleasure!"
Здравствуйте, Roter, Вы писали:
R>Подскажите пожайлуста, как мне выйти из такой ситуации?
Поиском пользоваться умеете? Это обсуждалось тут чуть не несколько дней назад.
Вам наверно стоит узнать, что такое сборщик мусора, к примеру, в статье GC в .NET
— и понять, что деструкторы, которые правильнее называть финализаторами, в управляемых средах ведут себя иначе, нежели в том же C++. В вашем случае нужно воспользоваться интерфейсом IDisposable и конструкцией using. MSDN-то под рукой нет что ли все эти азы прочитать?