Reputation: 3013
I'm hoping i know my facts correctly if not please correct me.
1) You use Dispose to clean unmanaged resources, that means no garbage collection for them.
2) Value types are stored on the stack, reference types are stored on the heap and pointers to reference types are stored on the stack(not really sure about this one but i think it's correct)
3) Finilizers are called by the Garbage Collector.
4) Garbage Collection is called by the CLR and not by the user(although the he can) for reference types, but value types are destroyed(sorry couldn't find a better word) when they go out of scope
I know about the using statement and the way i works but i think it would be a lot easier if the CLR would call Dispose for the user.
So my question is this: "If pointers to reference types are stored on the stack the compiler and the CLR, know when the object goes out of scope. Why does the compiler not generate some IL code that calls Dispose, or why doesn't CLR do that like they do for Finilizers and Destructors".
Sorry if my question is not clear, i'll gladly updated it with any other information you need. Thank you.
Upvotes: 0
Views: 975
Reputation: 81115
Given the code
void Blah(Thing Boz)
{
DisposableThing Foo = new DisposableThing();
Boz.SomeMethod(Foo);
}
the compiler would have no trouble determining that after the method exits, the reference Foo
will no longer be needed. If, at that time, there would be no other reference, anywhere in the universe, to the DisposableThing
identified by that reference, then that DisposableThing
should have its Dispose
method called before it's abandoned. The problem is that the compiler has no way of knowing whether SomeMethod
might have stored a reference to that object somewhere else.
In the vast majority of cases where an IDisposable
object is created, it will get passed into methods whose details the compiler knows nothing about. Consequently, the compiler has no way of knowing whether a particular reference to the object will be the only reference to the object at the time it goes out of scope.
If the method had been written as:
void Blah(Thing Boz)
{
using (DisposableThing Foo = new DisposableThing())
{
Boz.SomeMethod(Foo);
}
}
that would instruct the compiler to call Dispose
upon the newly-created object after Boz.SomeMethod()
returns. The compiler won't try to figure out whether Boz.SomeMethod()
might have kept a reference--the using
statement will call Dispose
regardless.
Upvotes: 0
Reputation: 99859
Classes can be written so unmanaged resources are cleaned up only by finalizers, with no use of Dispose
at all. In this case, the GC would clean up those resources "at some point" after they are no longer in use.
However, in some cases, leaving these resources claimed until an arbitrary point in the future is a problem. For example, if you open a system file handle, other applications may not be able to open the file until the handle is closed. By allowing application code to create and call a Dispose
method, the application can deterministically clean up unmanaged resources, ensuring the system does not enter a state just waiting for the GC to run "sometime".
Upvotes: 2
Reputation: 109537
Here's the problem:
If pointers to reference types are stored on the stack the compiler and the CLR, know when the object goes out of scope
That's an oversimplification. You can have private fields which are types that are disposable. These will not be stored on the stack, and the CLR cannot know when the object is no longer in use other than through the use of Garbage Collection. And of course, Garbage Collection already provides a mechanism - the finalizer - through which you can dispose unmanaged resources.
Upvotes: 4