Call .Dispose () for a class that has Finalizer

According to Essential C # 6.0, you should:

AVOID calls Dispose () on owned objects that have a finalizer. Instead, rely on the finalization queue to clear the instance.

  • Can anyone tell about this since I don’t understand what Dispose is if we don’t call it our own objects?
  • Besides Reflection, how would you determine if a Finalizer object has?
  • How do you know when to call Close() / Close() + Dispose() , besides searching for API documentation (if you have access to it and it exists) or Reflection? I see a lot of questions on the network for very specific types ( MemoryStream / Form / SqlConnection / etc.), but I look more at "how to figure it out yourself."

According to the Dispose Pattern, you must:

Using the CONSIDER Close () method in addition to Dispose (), if you close, this is the standard terminology in the scope. It is important that the Close implementation be identical to Dispose and consider using the IDisposable.Dispose method explicitly.

but there are times when you should call both types with Form , etc. Questions like “ Close and Dispose - which to call? ” Come closer, but there is no definite approach except

As usual, the answer is: it depends. Different classes implement IDisposable in different ways, and you decide the necessary research.

Editing: here is a complete guide, I did not ask permission to reproduce, but since this is a guide (thereby assuming that it should be freely shared with public knowledge) and not some part of the actual training material, I hope that I will not break any rules .

Recommendations
DO implement the finalizer method only on objects with limited resources or expensive resources, even if finalization delays garbage collection.
DO implement IDisposable to support deterministic finalization in classes with finalizers.
DO implements the finalizer method for classes that implement IDisposable if Dispose () is not explicitly called.
DO reorganize the finalization method to call the same code as IDisposable, perhaps simply by calling the Dispose () method.
DO NOT throw exceptions from finalizer methods.
DO call System.GC.SuppressFinalize () from Dispose () to avoid re-cleaning resources and delaying garbage collection on the object.
Make sure Dispose () is idempotent (you can call Dispose () several times).
Hold Dispose () simply by focusing on cleaning up the resources needed to complete. AVOID calls Dispose () on owned objects that have a finalizer. Instead, rely on the finalization queue to clear the instance.
Avoid linking to other objects that do not complete during finalization.
DOs call the Dispose () base class method when overriding Dispose ().
CONSIDER to make the object unusable after calling Dispose (). After the object has been deleted, methods other than Dispose () (which could potentially be called multiple times) should raise an ObjectDisposedException.
DO implements IDisposable for types that own disposable fields (or properties) and delete specified instances.

+5
source share
1 answer
  • Can anyone tell about this since I don’t understand what Dispose is if we don’t call it our own objects?

Without the full text of the book and its context (I do not have a copy of the book, and many other people cannot read your question), it is impossible to say exactly what they mean. But it should be a good book, and so I have to assume that the text you are quoting is for code only in your own finalizer. That is, of course, you must dispose of the owned objects in the normal mode. In your Dispose() method.

This is about what to do if your object has not been configured correctly. And the answer is simply to clean up your unmanaged resources.

This is due to the fact that now, with the advent (some time ago) of the SafeHandle class, you may not need a finalizer at all. Instead, wrap your own unmanaged resources in a SafeHandle subclass and let the class deal with completion.

  1. Besides Reflection, how would you determine if a Finalizer object has?

In addition to reflection, you rely on the source code (if available), documentation (if it is written), or simply the fact that the object implements IDisposable (i.e. makes the assumption & hellip; it is not guaranteed, but there is a strong correlation between them) . A.

Please note that since it is possible to correctly implement an object that implements IDisposable without using a finalizer (for example, if you use SafeHandle or if you implement IDisposable only so that you can deterministically clean up objects belonging to IDisposable ), the presence of a finalizer is not guaranteed.

I think the best way to talk about the manual is to "not destroy objects in your finalizer." Rely on the fact that the IDisposable object must somehow deal with the completion of its own resources and focus only on any unmanaged resources that the own object owns directly .. p>

  1. How do you know when to call Close () / Close () + Dispose (), besides searching for API documentation (if you have access to it and it exists) or Reflection? I see a lot of questions on the network for very specific types (MemoryStream / Form / SqlConnection / etc), but I look more at "how to figure it out yourself."

You can not. Not without a thorough study of the code. It is said & hellip;

You will never have to call either Close() or Dispose() . These two should always be equivalent if the class is implemented correctly.

Of course, there is nothing in .NET that provides this. So you can’t say for sure that you won’t need it. But if you are dealing with a type that requires both, it is poorly written and can be violated in other ways. It's best not to use this type at all. :)

And, of course, as you note, the Form class in some cases requires calling both Close() and Dispose() (in most cases, calling Close() is actually enough & hellip; only because of the strange way they implemented modal dialogs to get an exception to the rule). But this very old API, designed to fully understand the complexities of the IDisposable template, was really completely understood. One hopes that Microsoft will not develop this API as it would today if they had to repeat it again (and indeed, WPF does not have the same dichotomy).

Modern implementations should better follow subsequent good agreements more evenly.


Application:

I turned around a bit. There are, of course, many articles about GC, finalization, IDisposable , finalizers, etc. In Stack Overflow, but I have not seen a single one that would seem to be directly equivalent to your question. It seemed the closest, though:

What objects can I use in the finalizer method?

Others that may be useful for further reading:

When will the delete method not be called?
Why call Dispose ()? Memory leak won't happen?
IDisposable and Managed Resources

And, of course, classic:
Proper use of the IDisposable interface

+6
source

Source: https://habr.com/ru/post/1241110/


All Articles