Финализатор не называется - PullRequest
4 голосов
/ 05 марта 2011

У меня есть класс в C #, где я хочу правильно закрыть некоторые коммуникационные порты, когда мой класс утилизируется. Однако финализатор никогда не вызывается при выходе из программы. Это почему? Я что-то не так делаю?

Я вызываю распоряжение вручную, которое проходит и закрывает все коммуникации. Это тоже не срабатывает.

Вот финализатор, который я использую:

~Power()
{
    Dispose(false);
}

Ответы [ 4 ]

8 голосов
/ 05 марта 2011

Финализатор (который вы здесь используете) вызывается только на этапе Финализации, который произойдет во время GC.

Если вы правильно реализовали IDisposable, это никогда не должно вызываться. Я подробно расскажу об этом на моей серии на IDisposable .

При этом, если ваши "коммуникационные порты" обрабатываются через управляемые классы, вам вообще не следует использовать финализатор. Это добавляет накладные расходы, которые не помогут вам вообще. Просто реализуйте IDisposable (правильно) и позвольте управляемым оболочкам вокруг классов портов обрабатывать финализацию, если это необходимо.

5 голосов
/ 05 марта 2011

Если в лесу падает дерево, и вокруг никого нет, он слышит звук? Убедитесь, что он делает:

using System;

class Program {
    static void Main(string[] args) {
        new Test();
    }
}

class Test {
    ~Test() { Console.Beep(); }
}

Финализаторы любых объектов, оставшихся при завершении программы, вызываются непосредственно перед завершением процесса. Единственный способ, которым это не произойдет, это когда процесс грубо прерван. Environment.FailFast (), например.

4 голосов
/ 05 марта 2011

C # финализаторы не гарантированно будут вызываться в любое конкретное время.Их не следует принимать за деструкторы C ++.

Если вы хотите гарантировать предсказуемое удаление, внедрите IDispose и создайте экземпляр своего класса в блоке using:

using (Power power = new Power())
{
    //  blah blah
}

Если блок using не практичен, внедрите IDispose - вынужно написать метод Dispose, который избавляется от любых ресурсов, которые вам нужно выпустить;все точные требования см. в сети MSDN и явно вызовите Dispose () в соответствующее время.Если вы многопоточны, для этого может потребоваться некоторый код синхронизации, чтобы это не произошло слишком рано.

0 голосов
/ 05 марта 2011

Финализатор вызывается сборщиком мусора, и сборка мусора не является предсказуемым процессом, поэтому он не очень надежен. Вам нужно найти другие способы распоряжаться своими ресурсами.

...