Dispose x Close - c#

In overall cases, the Close method semantically just change the state of a object that can be changed again with the Open method, indefinitely.
In other hand the semantics of IDisposable.Dispose() method put the object in a state that cannot be undone.
So, why several answers about "close x dispose" and even MSDN pattern shows Close method calling Dispose ?

There is plenty of friction about this is the .NET framework itself. The implementation is however consistently without surprise, a class' Close() method always calls its Dispose() method.
Logically it always means the exact same thing. You explicitly say "I don't use this object anymore" in your code. So of course Close() just means the exact same thing as Dispose(). They both mean the exact same thing, "I'm done using it". So of course the implementation of these methods do the exact same thing.
Semantically it however does not mean the same thing. The big dog is the using statement.
You, preferably, never call Dispose() explicitly. The only place is should ever appear in your code is in your own IDisposable implementation. Which you need to implement when your class has members that implement IDisposable themselves. Which obliges you to implement IDisposable yourself, you simply implement it by calling the members' Dispose method.
Which is the only place you ever use it. In any other usage, you leave it up to the using statement inside of a method to automatically call Dispose() for you. With the corner-case that you don't want to dispose right away, you may need to keep the object around beyond the method call. That's when you use the Close() method.

Your initial statement:
In overall cases, the Close method semantically just change the state of a object that can be changed again with the Open method, indefinitely.
Is false. At least, it's false in terms of major .NET Framework classes.
In my experience, it's not often safe to write obj.Close(); followed by obj.Open();. Some classes support such behavior, but it's certainly not a hard and fast rule. I wouldn't bet that it's true in 50% of cases.
StreamReader.Close, calls Dispose. Stream.Close calls Dispose. SqlConnection.Close calls Dispose. From the SqlConnection remarks:
Close and Dispose are functionally equivalent.
I'm sure that there are cases in which Close does not call Dispose, but I would not suggest betting on the idea that Close can be followed by Open.

It's the other way around. Usually the Dispose method calls Close.
If the Close method of a class is implemented to call Dispose, then it's because closing and disposing are the same. Once you have closed it, you can't reopen it.

Related

Why does Subject<T>.Dispose does not dispose current subscriptions?

Hi I've been thinking for some time that Subject<T> disposes all the subscriptions based on it if you manually call its Dispose method. But I've recently found it doesn't work that way, it just clears its inner collection of observers and substitutes it with a DisposedObserver helper class instance.
I found myself a little confused about the behaviour, just assumed that the "normal" would be just propagate and dispose all the suscribers. Later, trying to figure out why is designed this way, I guessed a couple of reasons why they designed this way.
The suscriber may be a composition that depents partially on the subject , so full propagation of disposal doesn't make sense. ie. Merge is not disposed just because one of the sources was disposed, as everyone expects.
Subject.Dispose It is semantically equivalent to a continuation with Observable.Never from the side of the observer. The Subject.Dispose caller can also call OnComplete or OnError if wanted to signal error or completion before disposal (because they are on the same scope).
Edit Note:
Sorry for the unclear question. I already understand how to use it, this was more a design question. Let me state it more clearly.
Why do you think the designers of Rx made Dispose behaviour that way?
(the two points above are my answer trial)
A subject should indicate it is done by sending OnComplete or possibly OnError. This is idiomatically and grammatically correct Rx. Subscribers are responsible for ending their subscriptions by disposing them. You should write Observables such that they clean up resources once they are "done" even if subscribers have not unsubscribed.

Can I add an on close event to current thread

Is there any way to add an event to the current thread that is executed when the thread ends.
I have a solution where we create resources that we want to re-use but still need to have disposed when the thread ends to prevent leaks and I cannot trust every one to be diligent in adding manual dispose calls to their code.
I could do this with a wrapper around the thread but that will not be a reliable solution as I will not be able to make 100 % sure every one would use the wrapper and sometimes this might need to be added into an existing thread.
So I would need my resource to be able to add a dispose event to be called when the tread finishes.
Is this possible in C#
are we all talking about the same .net here? just impliment Finalize
http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.100).aspx
http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx
this is the way to tell the 'GC' to do some additional actions when clearing a resource.
If you expect developers may forget to call Dispose() on object, there is another pattern which can be used to force them to call such methods. This is inspired from how database transactions work.
The idea is you use the object which exposes two methods. Complete() and RollBack(). At the end of object lifespan, developer needs to call Complete() for things to work. If he fails to comply, object's destructor (or Dispose()) will call RollBack(). In .NET TransactionScope class is a good example.
In your case you need to encapsulate your thread object inside this class. The caller doesn't directly deal with thread object, but it deals with this class object.
Is there any way to add an event to the current thread that is executed when the thread ends?
No, there's no event in the framework that you can subscribe to.
As you say, one solution would be to wrap the thread main method with a try / finally block.
Another solution would be to rely on the GC. If someone forgets to call Dispose, the destructor will still be called some time after the object goes out of scope - it will be called on the finalizer thread, though.

How much work in the Dispose method?

How much work should be done in a Dispose method? In constructors I've always taken the stance that you should only do what is absolutely necessary to instantiate the object. This being the case I've also always taken the approach that you should ONLY be cleaning up open resources when disposing. Closing files, freeing memory, disposing of child disposable object, etc. You shouldn't be doing lengthy processes like touching files, accessing databases and such in the Dispose method.
Am I wrong? Are those action's OK as long as you are handling any possible exceptions so they don't bubble out of the method? I just don't think doing a lot in Dispose is a good idea. I would like to know what the community thinks.
Am I wrong?
No, you are right. In general the Dispose method is used to clean the unmanaged resources that your class might have allocated.
But that's difficult to generalize. There are cases where the Dispose method is simply used to ensure that some operation executes. For example in ASP.NET MVC there's the Html.BeginForm helper which is used like that:
using (Html.BeginForm())
{
}
and all that the Dispose method does is render a closing </form> tag. So as you can see people could be creative with the pattern and it is very difficult to draw conclusions without a specific scenario.
But in the most common situations it's used to release unmanaged resources.
"It depends". What kind of database/file access are we talking about? Say for example that your disposable object is some sort of logger and you use it in the following pattern
using(Logger logger = new Logger())
{
foo.PerformTask();
}
I think it would be perfectly acceptable for logger to write out "Log started" in the constructor "Log Completed" in Dispose.
How much work should be done in a Dispose method?
This depends, are you implementing the IDispose interface just for the convenience of a 'using' statement, or are you implementing the full IDisposable pattern? In the later case of a full disposable pattern it is still acceptable to perform more complex actions provided that you're 'disposing' parameter is true (i.e. you are not in GC).
When you are defining a finalizer that calls the Dispose method there really is not too much to be concerned about. Similar uses/abuses of the IDisposable interface mentioned already be others (i.e. using (Html.BeginForm())) are capable of performing any action. Often this can greatly reduce code complexity and prevent coders from accidentally forgetting to perform some closing action. One down (or up) side to this is that code executes a little differently inside a finally block.
In constructors I've always taken the stance that you should only do what is absolutely necessary to instantiate the object.
Objects, IMHO, should be valid post construction. So if you have a lot of work to do to construct something so be it. Don't think of the workload involved, think of the consumer of you're object and it's usability. Post-construction Initialize() methods suck ;)
This being the case I've also always taken the approach that you should ONLY be cleaning up open resources when disposing. Closing files, freeing memory, disposing of child disposable object, etc. You shouldn't be doing lengthy processes like touching files, accessing databases and such in the Dispose method.
Actually let's break this down a bit...
Disposing from the GC call to the Finalizer
When you implement the IDisposable pattern (not the interface, the pattern, finalizer and all) you are essentially saying that your object has an unmanaged resource that nobody else knows about. That means you have PInvoked a call to Win32's CreateFile, or maybe you called Marshal.AllocHGlobal or something like that. Essentially you likely have an IntPtr instance member you need to do something with to prevent a memory leak. These are the ONLY types of things that should be done when the disposing parameter is false (i.e. called from the finalizer on the GC thread).
Generally you DO NOT call the Dispose method on children. You should not expect any child object to be valid. Simply touching a member of the child object can accidentally 'revive' or resurrect it.
So when you are writing code that executes in a Dispose method called from the Finalizer you have to be careful. You are executing on the GC thread while the rest of your application waits for you. You should perform as few operations as possible to release the unmanaged memory/resource and quit. Never throw an exception and if you are calling an API that may throw you should catch any exception raised. Propagating exceptions back to the GC will prematurely abort the finalizer thread and the remaining objects to be finalized will not have a chance to clean up.
Disposing from the IDisposable.Dispose() method
As I’ve already said, using the Dispose method is safe enough and can safely accommodate any amount of code/process. This is where you would free unmanaged resources, call the dispose method of child objects, flush and close files, etc. Most of the Dispose methods I’ve written do not have an associated Finalizer and therefore do not follow the IDisposable pattern, yet they implement IDisposable just for the convenience of the using statement.
Am I wrong? Are those action's OK as long as you are handling any possible exceptions so they don't bubble out of the method? I just don't think doing a lot in Dispose is a good idea. I would like to know what the community thinks.
You are absolutely right when the dispose method in question is used from a finalizer. You’re assertions about what you should and should not do in a Dispose method should actually be reworded to apply to anything called by a Finalizer. The fact that this is generally done in a method called Dispose is a matter of convention, the IDisposable pattern, but these issues could easily exist in other methods used by the Finalizer.
If an object does something to the state of some outside entities in a way which makes them more useful to that but less useful to everyone else, the Dispose method of the object should do whatever is necessary to restore outside those entities to more generally-useful state. If one wishes to avoid having an object do too much work in Dispose, one should design the object so as never leave any outside entities in a state which would be onerous to clean up.
BTW, Microsoft likes to use the term "unmanaged resources", and gives examples, but never really offers a good definition. I would suggest that an object holds an "unmanaged resource" if an outside entity is altering its behavior on behalf of that object, in a fashion which is detrimental to other objects or entities, and if that outside entity will continue to alter its behavior until the object stops it from doing so.
You should lean toward the conclusion you have already come to. However there are situations where you need to ensure that services are stopped and that could include things like messages being logged for the service shutdown, or saving the current runtime state to data store. This type of disposal usually only applies to things that have a lifestyle that is application scope, meaning they exist the whole time the application is running. So there are situations outside of the expected norm. As is the case with every rule you should follow when writing code.

C# memory and dispose related questions

I have the following piece of code, just wanted to check who will call the dispose? is it called automatically.
ToolTip toolTip = new ToolTip();
toolTip.SetToolTip(button, toolTipText);
Also let say I create a Timer local variable, who will call the dispose, what about memory leaks, as, if I call the dispose right away, the timer event, won't be fired.
Do I need to make sure that in the timer event handler dispose is called, even if I don't have any reference to the timer variable. Also do I need to unregister the event handler for that timer.
Edit:
But how to call dispose on ToolTip, if I call it won't show.
Also why I need to Dispose the Timer, if I don't have any reference.
And Do I need to also unregister the timer event handler?
Also does keeping a reference increases the class memory footprint.
ToolTip registers event handlers on the control on which it is shown. It's Hide() method is automatically called when the form's Deactivate event fires. Which will happen when the form is closed. That in turn ensures that its Windows handle is destroyed and event handlers are unregistered. After that there are no disposable objects left.
You can verify this for yourself with Reflector or the Reference Source. Relevant methods are, in order, BaseFormDeactivate, HideAllToolTips, Hide, ClearTopLevelControlEvents.
You don't have to call Dispose(), you don't have a leak.
Dispose is a method provided to allow you to release the object immediately. For example an exclusive file stream.
Finalize is a method that automatically releases any resources the object is using once it is no longer being used by your program.
You only need to worry about disposing when the object uses exclusive or finite resources. Examples being the file one, or a database connection. (Note that in both these cases Close is equivalent to disposing)
To answer your question, you are not disposing at all, but letting the finalizer run when it needs to.
In .NET the garbage collector will automatically free memory when an object can no longer be referenced from anywhere. When it does so, if the object has a finalizer it calls the finalizer. The finalizer is for cleaning up, usually unmanaged resources.
However, finalizers are expensive (they delay garbage collection on an object, for example) and you cannot tell when it will be run (as you can't tell when the GC will decide to collect it). They are usually left as a last resort for cleaning up things like unmanaged resources.
This is where the IDisposable interface and it's Dispose method comes in. Dispose can also be used to clean up, both managed and unmanaged resources. When you call the Dispose method it cleans up and the object is no longer in a stable, usable state.
If you have a resource which implements IDisposable you can call Dispose on it when you know you are done. That way and resources it is holding on to can be freed up as soon as possible. The usual way of doing this is to wrap it up in a using statement, which will automatically Dispose when the using block is done. e.g.:
using (SomeDisposableObject disposableObject = new SomeDisposableObject())
{
disposableObject.DoSomeStuff();
disposableObject.DoSomeMoreStuff();
}
When the using block is finished (after DoMoreStuff) Dispose is called on disposableObject. Using statements are a lot cleaner than the equivalent code when you take into account exception handling.
In the case of something like ToolTip, which has unmanaged references (a lot of WinForms in a wrapper around the unmanaged Win32 components) it will have a finalizer to make doubly sure the unamanged resources are freed correctly. However, if you call Dispose on the object, the cleanup code is run there and then and the finalizer is suppressed (it won't run when the object is collection by the GC).
So, to answer your question more directly, if you know exactly when an IDisposable is finished with it is a good idea to call Dispose. However, if you don't it is usually ok just to leave it up to the garbage collector to collect it and call the relevant code to correctly cleanup the object.
In the cases of ToolTip and Timer given, I wouldn't worry about calling Dispose on them yourself as I suspect it would be difficult to predict when they will be finished with.
You need to call Dispose on anything that implements IDisposable, or at least make sure something does. For UI components, add them to a form's Controls collection and they'll get disposed when the form closes. For other things you need to keep a reference to them and call dispose appropriately. It may be appropriate to make your class implement IDisposable just to call Dispose on your composed objects.
Generally, it's up to the object registering to an event to un-register - not doing so will create memory leaks. You should not rely on a Dispose method doing so.
Dispose is not called automatically, unless you wrap the object in a using() {} statement, or add it to the objects IContainer instance (if it's a designer class). If it's a class variable, you need to make the containing class implement IDisposable and dispose of the instance in it.

Should GC.SuppressFinalize be called on objects that do not have a finalizer?

For some reason FXCop seems to think I should be calling GC.SuppressFinalize in Dispose, regardless of whether I have a finalizer or not.
Am I missing something? Is there a reason to call GC.SuppressFinalize on objects that have no finalizer defined?
There's no need to call GC.SuppressFinalize(this) in Dispose, unless:
You are the base class that implements virtual Dispose methods intended for overriding (again, it might not be your responsibility even here, but you might want to do it in that case)
You have a finalizer yourself. Technically, every class in .NET has a finalizer, but if the only finalizer present is the one in Object, then the object is not considered to need finalizing and isn't put on the finalization list upon GC
I would say, assuming you don't have any of the above cases, that you can safely ignore that message.
There is always a finalizer in IL - System.Object.Finalize() exists in every class, so if you make a custom class, it has a finalizer you want to suppress. That being said, not all objects are put on the finalization queue, so you only techncially should need to suppress finalization if you implement your own finalizer.
If you're implementing IDisposable to wrap unmanaged resources, you should include a finalizer, and you should prevent this from running, since in theory you're doing the cleanup already when Dispose is called.
It looks like FxCop simply inspects the Dispose() and doesn't check for the presence of a destructor.
It should be safe to ignore.
All objects have a finalizer method, even if you have not implemented one by using a c# destructor (which is not actually guaranteed to be called by the GC). It's just good practice to supress the call if you have implemented IDisposable because that means you have decided to perform the finalization explictly.
devx article
I don't see any need to call SuppressFinalize() if there's no finalizer defined. If you want to be defensive then it can be good to have a finalizer as well as Dispose(), so you don't need to rely on clients to always call Dispose(). Then you won't leak resources when they forget.

Categories

Resources