No resource is released because you used the command (not to be confused with the name import directive) using
. The only thing guaranteed that the using
is to call the method Dispose()
of an object, therefore, as already stated in the answer, it can only be used in objects that implement IDisposable
.
What you do within this method is not determined. Yes, the intention is to release unmanaged resources, but there are no guarantees that this will be done. In theory one can abuse.
Example
Taking an example of a question I answered:
using (FileStream fs = new FileStream("abc.txt", FileMode.Create)) {
// Algum código...
}
Is the same as:
{
FileStream fs = new FileStream("abc.txt", FileMode.Create);
try {
// Algum código...
} finally {
if (fs != null)
((IDisposable)fs).Dispose();
}
}
This example is a file that will be opened, linked to the application, will have some memory resource allocated by the operating system, and not by the application. NET, the operating system obviously controls all this access, and at some point it will need to be closed, that is, it needs to tell the operating system that it no longer needs this and that it can do whatever it wants with the resource. If you’re curious about see the source of this Dispose()
and follow where it goes.
Resources
These features are not processor, at least not under normal conditions, nor do I think it makes sense in this context. They’re not directly from memory either. While it is very common that these features may be in memory, this is part of something larger, it is something that your application has no direct control over. Obviously every resource physically exists only for you in the form of a memory chunk, but the resource is not just that, it’s all that’s around the administration of that chunk. Actually abstractly we can’t even think about it, that’s a detail that doesn’t matter.
Where they come from
It is common that these resources are:
- a file (on disk or otherwise) or other form of access to the operating system, such as mapped memory or Pipes,
- an access to his window system,
- a simple typographical font, which is a mix of a few things, as well as a graphic brush,
- anything the operating system can provide, including network resources, or a "simple" Mutex (class source).
In general this is done through a low-level API, usually made available for use with C (most languages can access them by some form of FFI.
Also several services installed on the machine can offer features, it can be an HTTP server or a database, an application of yours that has an API that does not conform to the . NET.
Because they need to be disposed of
In general all these features have a form of closure, release, removal that needs to be called when you no longer want to use them. If this mechanism is not called it will be attached to your application, probably occupying memory that the Garbage Collector do. NET does not care, even there is the possibility of leaving something locked for another use, or have other undesirable consequences.
Note that if the object has a Dispose()
it will be called sooner or later - if nothing very tragic happens in the application - and will make the release of the resource even if you have not used the using
or manually called (not recommended in most situations), but you can do later than intended and cause problems. The using
ensures that it occurs as soon as the resource is no longer needed, whatever happens within the application normality (even if you have a common exception).
Even if the system breaks unexpectedly it is clear that the feature will be released, a dead application cannot handle resources, this is guaranteed by the operating system.
We’re talking about the need to release something as soon as it’s no longer needed. Remembering that the garbage collector can run when only needed, there are no warranties for calling. In thesis you can do in any class your, but it would be an abuse and would not bring greater benefits, try to free managed memory with it does not work, by being managed by CLR, There’s nothing you can do to release her, if you need it (I can’t imagine a case that makes sense) you’ll have to think of another solution. In most cases it is only needed in lower-level classes.
There are cases where not releasing the resource is not a problem. In general in execution applications ephemeral and simple, is what I always talk about PHP. People care about rules and forget that there are exceptions.
C# 8
An interesting detail is that now (C# 8) no longer need to create blocks for the using
, only declare the variable without the block and the scope becomes the current block. Only this:
using var fs = new FileStream("abc.txt", FileMode.Create);
I put in the Github for future reference.
Completion
In the question example all cases are somehow tied to the database. A connection, for example, is something that your application has no control over. It needs to be "abandoned" as soon as possible (in general), it cannot wait for GC to work to warn you that you no longer need it. Well, I usually keep the connection active, whenever I can, and you don’t have to throw it away, but I don’t follow rules, I think to do.
in fact the assignment of
fs
is made within thetry
– Bruno Costa
@Brunocosta Do you have any source that shows this? As far as I know it’s out. I don’t remember where I got this from, but it was after a lot of research, it’s very likely that it’s information from Eric Lippert, who wrote the compiler that does it. I saw that people usually talk without paying attention how it really works. But I could be wrong.
– Maniero
After leaving the comment I reached the conclusion that makes no difference at all, for the little I had to see Oce is right.
– Bruno Costa