Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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".

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top