Why shouldn't Dispose () have control over managed resources and the finalizer?

We all know the System.IDisposable template. This has been described a million times, also here at StackOverflow:

reference: Dispose () to clean managed resources?

Disposable templates tell me that I should only manage managed resources if my object is located, and not during finalization

You can see this happening because it is recommended to use the following code:

protected void Dispose(bool disposing) { if (disposing) { // Code to dispose the managed resources of the class } // Code to dispose the un-managed resources of the class } 

I know that my class should implement System.IDisposable when my class has a (private) member that implements System.IDisposable. Dispose (bool) should call Dispose () on the private member if the logical order is true.

Why would this be a problem if Dispose is called during finalization? So why the next Dispose will be a problem if it is called during finalization?

 protected void Dispose(bool disposing) { if (myDisposableObject != null) { myDisposableObject.Dispose(); myDisposableObject = null; } } 
+4
source share
2 answers

Generally speaking, you should get rid of resources as soon as possible. If you do not need a resource, why would you save it in vain?

In addition, to call Dispose () during finalization, you will need to create a finalizer for your object, that is, a destructor in C #. However, the exact time the object finalizer is called is not deterministic, which means that at this point your managed objects may be inaccessible and inaccessible. Even the thread that your finalizer executes is not deterministic, which can also lead to problems that are difficult to anticipate.

For these reasons, finalizers must be created to free up unmanaged resources.

Very few programmers understand completely how the revision works. For example, the garbage collector recognizes that your type has a finalizer during object creation and places your instance in a special internal data structure called finalizequeue. In fact, when you debug your application using sos.dll (windbg), you can use the command! FinalizeQueue for displaying objects with finalizers and not yet completed at some later point in time.

+3
source

When the object finalizer completes, one of the following values ​​will be true for almost any IDisposable that may contain:

  • It contained a single reference to this other object, and that another object finalizer was already running, so there was no need to do anything with it.

  • It contained the only link to this other object and planned to launch another object finalizer, although it does not exist yet and there is no need to do anything with it.

  • Other objects still use the IDisposable object, in which case the finalizer should not call Dispose .

  • Another Dispose object cannot be safely started from the finalizer finalization context (or, more generally, any thread context other than the one in which the object was created), in which case the finalizer should not call Dispose .

Even in cases where none of the above actions is applicable, code that knows it will probably know a lot about its cleanup requirements, except that it implements IDisposable and often needs to use a more detailed cleanup protocol.

+2
source

All Articles