11

I have a class in C# where I want to close out some communication ports properly when my class is being disposed. However, the finalizer is never being called when I exit the program. Why is that? Am I doing something wrong?

I am calling the dispose manually which goes through and closes all communications. This is not fired either.

Here is the finalizer I am using:

~Power()
{
    Dispose(false);
}
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
Spenduku
  • 409
  • 4
  • 12
  • I'm guessing that your problem is not where you think it is. It's hard to tell without seeing more of your program, though. – Gabe Mar 05 '11 at 02:18

3 Answers3

10

The finalizer (which is what you're using here) is only called during the Finalization phase, which will happen during GC.

If you implement IDisposable correctly, this should never get called. I cover this in detail on my series on IDisposable.

That being said, if your "communication ports" are handled via managed classes, you shouldn't use a finalizer at all. This is adding overhead that does not help you whatsoever. Just implement IDisposable (properly), and let the managed wrappers around the port classes handle finalization if required.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • How do I implement IDisposable 'properly'? My class inherits usercontrol. I thought that implemented IDisposable? Clearly I may be wrong on this. – Spenduku Mar 05 '11 at 01:41
  • @Spenduku: I'd recommend reading my articles linked above. I explain this in detail, including subclassing an IDisposable class. What class are you using for your "ports"? – Reed Copsey Mar 05 '11 at 01:43
7

If a tree falls in the forest with no one around to hear, does it make a sound? Make sure it does:

using System;

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

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

The finalizers of any objects left at program termination are called just before the process terminates. The only way this won't happen is when the process is rudely aborted. Environment.FailFast() for example.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • And what happens when you put new Test() in another static function, call that new static Function from Main, and Application.Run(new Form1()) inside Main? I highly doubt GC will finalize that Test class until you close App or call GC.Collect(); ;) – SoLaR Mar 15 '18 at 07:02
1

Finalizer is called by garbage collector and the garbage collection is not a predictable process hence it is not very reliable. You need to figure out other means to dispose your resources.

Bala R
  • 107,317
  • 23
  • 199
  • 210
  • C# does not have destructors. Those things that use C++ destructor syntax -- they are *finalizers*. – Ben Voigt Mar 05 '11 at 01:50
  • The OP was referring to it as destructor and later got edited. – Bala R Mar 05 '11 at 01:51
  • @Ben Voigt: Actually, the C# Programming Guide calls them destructors: http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx – Jim Mischel Mar 05 '11 at 02:01
  • 7
    @Ben: They are called "destructors" in C# and "finalizers" in the CLR. It is unfortunate that the two teams chose different terminology; if we had to do it all over again, we'd probably try to be more consistent. But it is completely wrong to say that C# does not have destructors. C# has destructors; the spec calls them destructors, the documentation calls them destructors, and they are implemented by overriding the finalizer. – Eric Lippert Mar 05 '11 at 07:08
  • @Eric: The documentation is flat-out WRONG. [It says that "destructor syntax in C# and C++" are equivalent.](http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx) I've already filed documentation feedback. I think it's correct to say that "In C#, C++ destructor syntax is used to create a CLR finalizer." It is destructor *syntax*, maybe it can even be called a "C# destructor", but it is not a *destructor* in the general sense. So I'm going to continue to encourage people to use the word *finalizer*, it's unambiguous and obviously related to *finalization* in the C# and CLR specs. – Ben Voigt Mar 05 '11 at 15:30
  • 1
    @Ben: I encourage you to do that if it makes you happy. Regarding the documentation, I assume the line you are upset with is "Provide implicit control by implementing the protected Finalize on an object (destructor syntax in C# and C++)." Though that sentence is awkwardly written and probably not grammatical, I don't see any error in it, aside from the fact that it probably should have said C++/CLI rather than just C++. I wouldn't have used a parenthetical; I'd have written two sentences. – Eric Lippert Mar 05 '11 at 15:42