Box debris from IDisposable

I talked to a man about the use () statement.

He said that if we do not use the using statement () to something like the StreamWriter, if there is any exception, the resource will NEVER be assembled.

I understand how to use the using statement (), but I do not agree with the fact that life will never be collected. I think that with the help of () operator will call the dispose () method at the end that can make the collection more quickly. However, even if we do not use use (), we do not call the dispose (), the resource can still be collected by the collection envelope, although it may take much more time.

With whom do you agree?

ps. I know what you're talking about. It is important to use the manual (). I just want to find out whether the resource will definitely never get if we do not?

+4
source share
7 answers

Clarify this. Suppose that the resource is a file descriptor. The garbage collector does not know anything about the file descriptor, or how to release him. The file descriptor is an integer.

If the StreamWriter, which clings to the file descriptor gets garbage collection, the garbage collector places the object in the finalization queue. When the turn is complete is complete, it is called the finalizer of the object, and this is what frees the file descriptor.

It's all clear? The garbage collector does not release the resource; the only resource which knows the garbage collector - are objects in memory. Before the object is released, it will be completed, so the object itself knows how to release the resource.

+10
source

using(x) is a deterministic model. This ensures that the Dispose() is called to implement, when transmitted to a particular point in the execution stream. On the other hand, the GC is not deterministic, because you do not know exactly when the object is actually deleted. using guarantees that the object will perform its cleanup code (whatever that is), when you expect it, not some time in the future.

+4
source

If the links to the StreamWriter is no more, eventually it will be garbage collection, but it depends on the garbage collector, if so - it is not determined, so you always have to use the blocks using , when you can.

+2
source

You should always call Dispose() , when you are finished using the object IDisposable . A using - a great tool for this rule.

The purpose of IDisposable is to allow classes to dispose of unmanaged resources, which will not be automatically cleaned of garbage collection.

If you use an object IDisposable without calling Dispose() , when you're done, you risk never manage resources properly, even after the garbage collection.

That is why there is an operator using ; it provides a convenient syntax for using objects IDisposable and defines a clear area in which these objects can be used.

Please note that the garbage collector never calls Dispose() itself, but also note that it is recommended to follow the Finalize / Dispose, as described in the MSDN . If the object follows the pattern Finalize / Dispose, Dispose() is called when the GC is finalizer.

+1
source

I talked to a man about the use () statement. He said that if we do not use the using statement () to something like the StreamWriter, if there is any exception, the resource will NEVER be assembled.

Operator using has nothing to do with garbage collection. Once an object has live links, it becomes eligible for garbage collection.

I understand how to use the using statement (), but I do not agree with the fact that life will never be collected.

Oh, then you're right.

I think that with the help of () operator will call the dispose () method at the end that can make the collection more quickly.

He may or may not make the collection more quickly. To dispose method typically cause GC.SupressFinalize(object) , which means that the finalizer will not be called when the object is collected debris. Instead, the object is simply assembled. Thus, it can make the collection more quickly.

If you intend to say that it makes the object collected immediately, and not later, then it will be incorrect. Eligible items are collected every time the garbage collector walks up to him, more than ever, and the object is appropriate, as soon as he has no links to the live links, for which the operator using little effect. In fact, since the finally block to use manual contains a live link, I can imagine a scenario in which it could increase the lifetime of the object, but this effect is not considered, because the lifetime management of the object is not a use-point, determined by the removal of unmanaged resources is point of use statement.

However, even if we do not use use (), we do not call the dispose (), the resource can still be collected by the collection envelope, although it may take much more time.

Again, use Dispose and usually do not affect the lifetime of the object. This affects only the state of unmanaged resources (provided that the Dispose method is implemented correctly). You are right that the object will still be collected.

+1
source

It is used, essentially the same as the following (check of IL, if you doubt this):

  try { IDisposable o = new Object(); } finally { o.Dispose(); } 

As long as the object in question implements the IDisposable, called Dispose () method, and resources, will be something stupid, encoded in the Dispose (), will collect garbage. When? The question I can not answer.

Is it possible that an element will never be GCed. Well, there is never a long time, but it is theoretically possible, if it goes beyond the first generation, and just sits there. Problem? No, if the memory is eventually required, it will be cleared. Often seen, wrongly, as a memory leak? Sure.

0
source

If StreamWriter is created with the flow, which will be used by other code even after the StreamWriter will be left, do not call Dispose in StreamWriter. If the thread is left by its owner after the StreamWriter transmission, it is necessary for the correct call Dispose in StreamWriter.

In retrospect, the StreamWriter, probably had to have the implementation of IDisposable do-nothing, but had a streaming class StreamOwningWriter, the implementation of which would have to pass the transmitted stream. Alternatively, he could have a constructor parameter and property to specify whether he should be removed stream when called his own method Dispose. If any of these approaches has been taken, then the correct behavior would be to always call Dispose in StreamWriter (and let "StreamWriter" (which can be StreamWriter or StreamOwningWriter) worries about whether Dispose has to do anything)

0
source

All Articles