What is the meaning of Finalize and Dispose methods in .NET? (see details before replying)

I need to clear resources during object break, but I always found the differences between Dispose , Finalize , and the destructor methods were a bit confusing.

I found this wonderful article that briefly describes the differences between them that I will need to keep for future reference:
"The Difference Between Destructor, Dispose, and Finalize Methods" - Sanjay Saini http://sanjaysainitech.blogspot.com/2007/06/difference-between-destructor-dispose.html

The main question I ask here is this.

If the language offers destructors (for example, C # [refuted]), what do do Dispose and Finish add to the equation?

Am I just a caster who is used to the old school way of doing everything in the destructor, or is there something that I am missing, which is only possible by breaking the object in three pieces?

UPDATE:
As noted in some answers, C # actually has no destructors. At this point, the issue may be controversial in recognition of this. When I read in the aforementioned article citing that C # actually had a separate deconstructor (the error is explicit), it threw me into a loop, and I began to wonder what Dispose and Finalize would be if you had last destructor to wrap everything up, I believe that in a GC langauge like C #, the concept of a single destructor to provide a denemount for an object doesn't make much sense.

Sorry for the downvotes for some of you guys, but a couple of people did not carefully read the question and thought that I was asking about the difference between Dispose and Finalize, which is really not the case.

+4
source share
9 answers

The author of this blog post is a bit confused ...

There is no such thing as a "destructor" in C #. Only finalizers and IDisposable.

The ~ ClassName () method is not called a destructor. It is called a finalizer.

Dispose exists to free resources from code where there is a finalizer to invoke from the GC. Very often, the finalizer calls the Dispose () method, but the "Dispose Pattern" allows you to process unmanaged resources only from the finalizer.

You see, when the finalizer is called, you are in a different thread, and any managed entity that you have is not necessarily valid. Because of this, if you call Dispose () from the finalizer, you really need to call Dispose (false), which tells the "Dispose Pattern" to use only unmanaged resources.

In addition, the “Dispose Pattern” assumes that when you call Dispose (true), you must suppress the finalizer on this object.

+7
source

Only managed objects can be finalized automatically. If you want to suggest implicit removal of unmanaged objects, you can use Finalizer. If you want to offer explicit control over the removal of the caller, you can allow them to call Dispose.

I like this article .

+4
source

What looks like a destructor in C # ( ~Foo() ) is just another way of writing "Finish".

Perhaps in retrospect the choice of syntax was not the best, because ~Foo() in C # is very different from ~Foo() in C ++.

+2
source

This is hard to answer as you are already citing articles explaining the difference.

But let me try it anyway.

With garbage collection, you have non-deterministic memory management, and since the GC starts your finalizer, you guarantee, but not deterministic resource management.

This is good, in the sense that you know that things will be cleaned.

However, this is bad, because you do not know when this will happen.

For example, if you open a file and lock it while you open it, not knowing when the file will be available for opening again later, this is bad, but the guarantee that it will be closed at some point is good.

Dispose and IDisposable serve for this bad part by adding deterministic resource management. You choose when you need to manage your resources, close a file, network connection, database connection, whatever. This is your choice, and you usually get rid of the resource when you no longer need it. That way, when you no longer need the file, you delete it so that it remains open. The object will remain in memory (without deterministic memory management) even longer, but the file will be closed when you say so, ready to open again immediately.

Thus, you get deterministic processing of resources and combine this with non-deterministic memory management, and you get the best of both worlds.

+2
source

C # does not offer destructors, so your question is somewhat controversial?

+1
source

The problem with waiting for the finalizer to launch to release resources is that it does not work in a predictable deterministic manner. The finalizer is called when the GC is ready to destroy the object, and this can happen at any time in your application.

That is why you dispose. This allows you to determine the release of resources at a known point in time, ensuring that resources are released. Otherwise, you cannot control the finalizer.

+1
source

Finalize cannot access managed objects, so the managed object must be processed in Dispose. The difference between the two is that you should use Dispose for managed and Finalize for unmanaged. Your Destructor must call Dispose so that you clear the memory correctly. Take a look at the following articles:

The project code is IDisposable: what your mother never told you about releasing Gil Fink resources - Memory leak and IDisposable template

+1
source

Sorry to answer my own question, but I think that I have collected from various sources, including some of the answers, a short answer to my question regarding the differences in the life cycles of objects when switching to the GC platform.


Life cycle of objects without GC:

Initialization: Occurs in the constructor, which is called when the first reference is added to the object.

Cleanup: Occurs in a destructor that is called when the last variable reference object goes out of scope or is explicitly set to nothing / zero / another object.


GC Object Life Cycle:

Initialization: Occurs in the constructor, which is called when the first reference is added to the object.

Cleanup (first pass): Occurs in the Dispose method, which must be explicitly called by the client or implicitly called at the end of the Using statement. This cleanup is designed to free up resources that should be released immediately, rather than waiting for the GC.

Final Pass: Occurs in the Finalize method, which is called on the GC schedule, which can be delayed. If the finalize method is implemented, it is called if GC.SuppressFinalize was previously called on an object (usually from the dispose method) to mark it as already cleared.


I got it right? Feel free to edit if I missed something.

+1
source

I'm not sure about the reasoning between Destructors and Finalizers, but Dispose exists so that you can free up resources before the garbage collector gets to the object (which may never be!)

0
source

All Articles