Are there situations where use will not destroy the object?

Are there situations where use will not destroy the object that it should be disposed of?

For instance,

using(dbContext db = new dbContext()){ ... } 

is there any way that after the last } db still exists?

What to do if there is such a situation:

 object o = new object(); using(dbContext db = new dbContext()){ o = db.objects.find(1); } 

Is it possible that o can keep db alive?

+4
source share
10 answers

I think you are mixing two concepts: garbage collection and collection.

Removing an object frees up the resources used by this object, but this does not mean that the object was garbage collected. Garbage collection will only happen where it is no longer a reference to your object.

So, in your example, db.Dispose (which closes the connection) will be called at the end of the using block, but DbContext will still refer to o . Since o is a local variable, DbContext will have the right to garbage collection when the method returns.

+6
source

Alive and Disposed are two different things.

If o is an object that contains a link (via a field, property, itself, etc.) to the dbContext object, and the garbage collector determines that both o and the dbContext object are still accessible, then this object will be stored in alive. However, the object will still be deleted as soon as the execution exits normally from the block in use.

+5
source

db will remain until it goes out of scope, all references to it will be lost, and GC decides to attack. Calling Dispose does not clear the object itself; it tells the object to clear whatever it holds.

The IDisposable interface is managing your own resources that the GC cannot manage. The object itself is the managed entity that the GC takes over. In your example, this object probably maintains a connection to the database, which is a native resource.

The GC cannot clear it, so for the deterministic management of this memory / resource, the class implements IDisposable to tell clients "hey, you need to do a little extra work to ensure that the resources that I need to do my work will take care as efficient as possible."

By the way, the correct implementation of IDisposable will result in the release of any native resources in the finalizer, so you should not experience a memory leak if you do not call Dispose . However, this is not deterministic, and you can experience problems very well by doing this. Good practice dictates that you release these resources as soon as possible, which is why you yourself call Dispose .

+4
source

An object may be alive from the point of view of the GC after the end of the used block, but it will be deleted. In your second example, if db.objects.find(1) returned a link to db (which would be strange), you would have something like this:

 object o; using (dbContext db = new dbContext()) { o = db; } // at this point in the code, the object is disposed, but referenced by the variable o; the object is therefore not yet eligible for garbage collection. 
+2
source

Is it possible that o can keep db alive?

Alive in the sense that he is not going to: Yes.

But the using() {} block implies Dispose() , and that implies Close() , so you can no longer use it for anything meaningful.

+2
source

using ensures that IDisposable.Dispose will be called on the target when execution passes from the using block. It will always happen, no matter what.

It's unclear what you mean by that that o can contain db alive - db , so you will probably get an ObjectDisposedException if you try to use it later. Is it considered "dead"? If so, then he is dead, Jim.

+1
source

Setting an object to a specific instance does not support live database connections. Now, technically, this is not realistic, since there is a pool to keep these expensive objects alive, but from your point of view, it works the same as the located object and calls the Dispose () method.

If you really set o = db, it will be a different story, but you are dealing with result sets.

NEW: One more thing. Depending on how Dispose () actually executes, you may see an exception if the object cannot be deleted.

BTW, the using statement is essentially the same as this one (compile and analyze using a reflector if in doubt):

 try { var myObject = new MyObject(); } finally { myObject.Dispose(); } 
+1
source

using construct is equivalent to try-finally block:

 dbContext db = new dbContext(); try { o = db.objects.find(1); } finally { db.Dispose(); } 

In most cases of normal program execution, db.Dispose () is called. However, this does not mean that db will still not be a valid object in memory. As Ed said in his answer, Dispose () does not actually remove the object from the heap and free up memory. This only happens when the object currently referenced by the db variable loses all references (because they are out of scope or reassigned) and GC deletes it.

However, an object being located is usually not very useful for storage in memory; Dispose () is usually the end of the road before the object goes out of scope and is GCed. Therefore, despite the fact that you can keep db around by creating or assigning a link to it with another variable, you are likely to cause errors due to the object closing its connections, releasing unmanaged resources such as COM links or sockets, and, as a rule, he himself prepared for removal from memory with a call to Dispose ().

+1
source

No, db will always be deleted.

Do not mix the concept of disposal of an object and an object collected by the GC. Disposal is a tool to free up resources used by an object, but you can always keep a live link to an object that will not allow you to collect the object. One does not exclude the other.

The Dispose pattern is just a way to deterministically free resources even if the object is not collected by the GC (which will be done if there are no live links and when the GC decides to assemble an object that cannot be known in advance unless you explicitly name GC.Collect ).

+1
source

To add another point of view to all answers ("disposed" vs "garbage collection").

Some objects have internal resource caching, which are partially processed by the IDisposable template. That is, you can create a type that controls access to a specific file. Each instance will read / write part of the file, but Dispose from one of many instances will not close the file until the last instance associated with the file is deleted.

Since "use" does not do any magic things, it will follow an object contract on the part of "closed resources", but perhaps this does not necessarily mean "a special resource is now free." Thus, after using the object, it can definitely be โ€œdeletedโ€, it can be โ€œaliveโ€ from the point of view of the GC, and the actual resource that the object controls may or may not be freed (ie Unloaded from memory / built-in descriptors).

+1
source

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


All Articles