Как выполнить операцию до того, как объект будет уничтожен? - PullRequest
2 голосов
/ 22 ноября 2010

Работа с C #.У меня есть абстрактный класс, который я использую для чтения / записи настроек в XML-файл.Когда класс больше не нужен, я хочу выполнить одну последнюю операцию записи в XML-файл, прежде чем класс будет удален.Я попытался поместить этот код в метод деструктора ~myClass() {}, но он выдает исключение, говорящее, что безопасный дескриптор закрыт.Я предполагаю, что это означает, что класс уже утилизирован или частично утилизирован.Так что, если деструктор не является правильным местом для этого, где находится правильное место?Мне нужно реализовать IDisposable или что-то?

Ответы [ 4 ]

3 голосов
/ 22 ноября 2010

В C # нет такого понятия, как destructor s.Пожалуйста, обратитесь к принятому ответу на этот вопрос от Джона Скита, который объясняет и предоставляет хорошую статью по этой теме.Sample use of a C# Destructor

Кроме того, возможно, стоит подумать о реализации интерфейса IDisposable в вашем классе, чтобы вы могли выполнять свой маневр.

2 голосов
/ 22 ноября 2010

Существует множество потоков в финализаторах SO, просто прочитайте несколько из них.

Суть в том, что вам никогда не следует полагаться на финализаторы, поскольку их порядок выполнения не определен или может вообще не выполняться.Вы должны использовать IDisposable для любой управляемой очистки (ваш случай) и SafeHandles / CriticalFinalization для собственных ресурсов.

0 голосов
/ 02 декабря 2010

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

0 голосов
/ 22 ноября 2010

Похоже, сегодня вы пытаетесь записать файл настроек в финализаторе вашего объекта, используя поле SafeHandle.Это не правильный подход.

Как только объект попадает в поток финализатора CLR, все ставки отключаются относительно других управляемых ресурсов, которые может видеть объект.Это очень законно и возможно, что поле SafeHandle уже завершено и, следовательно, недействительно к моменту запуска финализатора содержащего класса.

Стандартный способ работы с таким сценарием заключается в реализации IDisposable и использовании метода Dispose (который должен вызываться кодом пользователя) для правильной утилизации управляемых ресурсов, например файла,

Например:

abstract class MyClass : IDisposable { 

  private SafeFileHandle _handle;

  public void Dispose() { 
    WriteTheFile();
    _handle.Dispose();
  }

}
...