Исключение в деструкторе (c #)? - PullRequest
3 голосов
/ 28 марта 2012

У меня есть этот класс:

public class TempFileRef
    {
        public readonly string FilePath;

        public TempFileRef(string filePath)
        {
            FilePath = filePath;
        }

        ~TempFileRef()
        {
            File.Delete(FilePath);    //<== what happens if exception ?
        }
    }

Вопрос:

Что произойдет, если в деструкторе есть исключение?

1) сломает ли он другие финализации в F-очереди?

2) Я оберну его Try и Cache - NEVER узнаю, что произошла ошибка

3) what мне делать здесь?

редактировать

Шаблон MSDN для него на основе "if I **forget** to call the Dispose method - so the GC will do it eventually.... it is better later then never...". Так что мой вопрос специально об исключении в Finilize (деструктор)

Ответы [ 4 ]

14 голосов
/ 28 марта 2012

Это на самом деле зависит от .NET Framework

Например, в .NET 2 и .NET 4 ваше приложение будет закрыто

Если Finalize или переопределение Finalize выдает исключение, и среда выполнения не размещается приложением, которое переопределяет политику по умолчанию, среда выполнения завершает процесс, и никакие активные блоки или финализаторы try-finally не выполняются.Такое поведение обеспечивает целостность процесса, если финализатор не может освободить или уничтожить ресурсы.

В отличие от .NET 1 , только этот финализатор будет прерван, а ваше приложение продолжит работу:

Если Finalize или переопределение Finalize выдает исключение, среда выполнения игнорирует исключение, завершает этот метод Finalize и продолжает процесс финализации.

То, что вы на самом деле пытаетесь сделатьdo - реализовать шаблон IDisposable, поэтому вместо того, чтобы оставить эту работу для finilazer, выполните ее в программной форме Dispose.

9 голосов
/ 28 марта 2012

С MSDN :

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

6 голосов
/ 28 марта 2012

Вместо удаления файла в финализаторе рассмотрите реализацию интерфейса IDisposable.

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

http://msdn.microsoft.com/en-us/library/aa664609%28v=vs.71%29.aspx

0 голосов
/ 28 марта 2012

Не используйте Destructor, это не C++, используйте Dispose() метод интерфейса IDisposbale, который вы должны реализовать.Вызовите Dispose () специально из вашего кода или используйте ваш класс с using, например, скажем,

using(var tempRef = new TempFileRef())
{
    //do something here

} //Dispose will be called after this line.

EDIT

Согласно документация

Если Finalize или переопределение Finalize выдает исключение, и среда выполнения не размещается приложением, которое переопределяет политику по умолчанию, среда выполнения завершает процесс и не выполняет активную попытку-окончаниеблоки или финализаторы выполнены.Такое поведение обеспечивает целостность процесса, если финализатор не может освободить или уничтожить ресурсы.

Другими словами: не вызывайте в Finalizer что-либо, что может дать сбой.Вместо этого используйте Dispose и убедитесь, что он вызван.

Надеюсь, это поможет.

...