Good samples of using Finalizers in C#
Asked Answered
A

2

16

When I read a few articles about memory management in C#, I was confused by Finalizer methods.

There are so many complicated rules which related with them. For instance, nobody knows when the finalizers will be called, they called even if code in ctor throws, CLR doesn't guarantee that all finalizers be called when programs shutdowt, etc.

For what finalizers can be used in real life?

The only one example which I found was program which beeps when GC starts.

Do you use Finalizers in your code and may have some good samples ?

UPD:

Finalizers can be used when developpers want to make sure that some class always disposed correctly through IDisposable. (link ; Thanks Steve Townsend)

Anglofrench answered 3/11, 2010 at 15:9 Comment(4)
I've only ever written a handful of finalizers in the last 5 years of projects I've worked on and they were all for classes that were inter-operating with a legacy unmanaged API. Under normal operation, the finalizers were never actually called, because the objects were Disposed before they became eligible for garbage collection, and finalization was explicitly suppressed.Nydia
@Dan Bryant - yes - did not see this before making this point my answer...Catacomb
I always thought finalizers were there to dispose unmanaged resources as a fail safe in the event the IDisposable.Dispose() doesn't get called (somebody forgot to use using() or finally), and they cause no perf issue as long as your Dispose() calls SuppressFinalizeMadras
So, when it is not a critical to hold some unmanaged resource for a undetermined time, we can use finalizers in case programmers forgot call Dispose(). In other case, when it's important that some resource must be disposed in determinate time, we should use finalizers to debug that objects disposed correctly. Did I do the rigth resume?Anglofrench
C
6

There is an exhaustive discussion of Finalizer usage, with examples, here. Link courtesy of @SLaks at a related answer.

See also here for a more concise summary of when you need one (which is "not very often").

There's a nice prior answer here with another good real-world example.

To summarize with a pertinent extract:

Finalizers are needed to guarantee the release of scarce resources back into the operating system like file handles, sockets, kernel objects, etc.

For more correct real-world examples, browse around affected classes in .Net:

https://learn.microsoft.com/en-us/search/?terms=.Finalize&scope=.NET

One valid reason I can think of when you might need to use a finalizer is if you wrap a third-party native code API in a managed wrapper, and the underlying native code API library requires the timely release of used operating system resources.

Catacomb answered 3/11, 2010 at 15:12 Comment(0)
C
5

The best practice known to me is plain simple don't use them. There might however be some corner cases when you want to use a finalizer, particularly when dealing with unmanaged objects and you can't implement Dispose pattern (I do not know legacy issues) then you can implement Finalize method with caution (and it could reduce the performance of your system, make your objects undead and other possibly weird scenarios, minding the exceptions as they are uncatchable:)).

In 99% of cases just write the use Dispose pattern and use this method to clean after yourself and everything will be fine.

Carburet answered 3/11, 2010 at 15:20 Comment(3)
I can't understand what you're saying here (you might want to formalise this a bit) but I'm 100% sure that in 99% of cases you don't want to go near finalisers.Tokoloshe
That's precisely what I am saying. I might edit the answer then if it's unclear. Finalizers are dangerous and need a lot of caution when implementing them. And as guys said before me, they are only needed when dealing with some unmanaged resources. But interfacing with legacy technology or using some c/c++ libraries might sanction using it.Carburet
A class should almost never have a finalizer unless the class's purpose revolves around it having one (as is the case with e.g. SafeHandle). If a complicated object is going to demand exclusive use of something which will outlive it, it should create another object whose sole purpose is to manage that thing. Many complications arise if an object with a finalizer holds references to other objects, which may in turn hold references to other objects, etc. It's ironic that the Dispose pattern provides explicit support for having a derived class add a finalizer--I doubt that's ever a good idea.Dotted

© 2022 - 2024 — McMap. All rights reserved.