C# Dispose : when dispose and who dispose it - c#

I'm getting in nerve between dispose and finalize. Here is my example code:
public class Car:IDisposable
{
public string name;
public Car()
{
name = "My Car";
}
public void Dispose()
{
Console.WriteLine("This object has been disposed");
}
}
public static void Main()
{
Car anotherCar;
using (var car = new Car())
{
anotherCar = car;
Console.WriteLine("Before dispose. Name is: "+anotherCar.name);
}
Console.WriteLine("After dispose. Name is: "+anotherCar.name);
}
The result is:
Before dispose. Name is My Car
This object has been disposed
After dispose. Name is My Car
My question is : because C# will automatically dispose object after using{}, so I think at line "After dispose". anotherCar.name must be NULL. why it still be "My Car" ?
And my another question is : my book said that you shouldn't use GC.Collect() for some reason and one of these is Performance. So, who dispose object ? If that is Garbage Collector,too so I think dipose() has the same performance issues with finalizer()
Thanks :)

I think you are misunderstanding what Dispose actually does. It doesn't destroy your object, set anything to null, or otherwise perform any sort of magic. When you use the using statement, that just guarantees that Dispose will be called. What you do in your Dispose method is what determines the behavior of your object. Not the language or .NET framework.

If you look at the code again you will realize immediately that simply putting a Dispose() method on a class and implementing IDisposable does not add any behind the scenes magic, it is just a normal method with the added convenience that it will be called at the end of an using statement.
Generally in the Dispose method you should take care of clearing any (unmanaged) resources you want freed by yourself, for example closing a db connection or a file which was open for reading/saving...
Microsoft has a nice help page about implementing IDisposable correctly.

An object in .net is generally a combination of a type reference and the public and private fields required by that type (there are a few special cases like arrays and strings). Once created, an object in .net will continue to exist as long as some form of reference to it exists. Once there are no longer any references to an object, if will effectively cease to exist; any memory it had occupied will simply be unused memory, eligible for reuse at the next garbage collection.
The purpose of Dispose is not to destroy an object, but rather to allow an object to perform necessary actions with things outside itself before it disappears. As a simple example, suppose an object asks a remote server to grant it exclusive access to a file; the server supplies a token, with a promise that access will only be granted to code supplying that token. If the object were to simply disappear, the external server would leave the file locked for the exclusive use of code that holds a token that no longer exists. In other words, the file would be forever(*) unusable by anyone. Adding a Dispose method to the object which asked for the token would allow the object to sent the server an "Okay--I'm done with file XYZ1493" message, thus making the file available to other entities.
Note that the Dispose method doesn't actually destroy the file object. It may prompt the object to erase some of the data stored in its fields, but the object will continue to exist as long as any reference to it exists, and will cease to exist thereafter. There are some cases where calling Dispose on an object may hasten the demise of the object itself, by asking other outside objects which hold references to it to destroy those references. Even in those cases, however, the purpose of Dispose is to allow objects to issue requests to other things.

Related

Declaring and disposing a local variable in a function/method in .Net

Until recently it never really bothered me as to how to best declare and dispose of a local variable but I thought I'd ask once and for all and get some feedback as it's starting to bug me more and more these days.
When creating a function/method that creates a local object, which method is best to create and dispose of the object.
For simplicity sake, assume that the method of the object being called will never generate an exception i.e. ConvertThisToString
private string myFirstFunction()
{
MyDataType myObject = null;
try
{
myObject = new MyDataType();
return myOjbect.ConvertThisToString();
}
finally
{
myObject = null;
}
}
or
private string mySecondFunction()
{
MyDataType myObject = new MyDataType();
return myOjbect.ConvertThisToString();
}
Are both functions ok and is it just about coding preferences or is there one method that's better than the other? Why?
My opinion is that one always requires the try/catch in order to nullify the object, which might be an overkill of try/catch for nullifying's sake, while the other method doesn't call any explicit way to destroy the object, which might be to reliant on .NET GC to release it from memory.
Should I be using the "using" statement instead?
Well, this is probably an incorrect statement. Is a local object immediately destroyed and disposed of when leaving a function or will it be cleared at a later stage by the GC management or other.
Thanks for feedback.
Thierry
UPDATED:
Removed the catch block as it caused confusion in my question. Should haven't been there in the first place since I did say, no error would ever occur.
That's very wrong.
Don't swallow exceptions.
Assigning a variable to null at the end of its scope will not help the GC at all.
If your object actually has expensive resources, it should implement IDisposable (correctly!), and you should dispose it using a using statement (but only when you're finished with it!)
You don't need to assign to null. When the object leaves scope, it will automatically be eligible for GC. There is no need to do anything special.
Basically, just write the second, simple version.
Should I be using the "using" statement instead?
If your object is wrapping resources (not memory allocated via new ..., but native resources) and implements IDisposable, then yes, you should use the using statement to guarantee those are cleaned up.
Is a local object immediately destroyed and disposed of when leaving a function or will it be cleared at a later stage by the GC management or other.
It will become eligible to be collected. At some point in the future, the GC will clean it up, but the time when this happens in indeterminant.
The best approach here is the Using statement.
something like this:
private string myFirstFunction()
{
using(MyDataType myObject = new MyDataType())
{
return myObject.ConvertThisToString();
}
}
this will dispose the object after execution.
As with almost everything, it all depends on what object you are using. If the object you are creating implements IDisposable then you would be best served to place in a using (typically). Outside of that most objects will get cleaned up by the garbage collector. IF you are the producer of a class that accesses COM objects then as the producer you should have provided a away for a proper cleanup, e.g. implement the IDisposable interface and handle the Dispose() correctly. As others have commented swallowing exceptions or even try/catching EVERY method doesn't seem like a reasonable or good idea. If a call you are making has the potential of throwing an exception and you have unmanaged or leaky objects then you should handle via a try/finally or a using (again, if appropriate).
You don't need to use a try/catch/finally to set a variable to null. The .NET GC will clear up any unreferenced classes when a method ends in it's own time.
If you are doing something really intensive (more so than your sample shows) then you can set the variable reference to null as a pointer to the GC that this is no longer referenced. This will only make a difference to your program if you are doing something which ends up marking the variable reference for Gen2 collection and then you do more stuff which prevents the GC collecting your variable (because the scope has not been left - in this case the method).
This is a bit of an extreme case as the .NET GC is designed to remove this aspect of programming from your daily concern, and regardless, it should get cleared up when the scope ends - it might just a bit longer.
You use 'using' if the referenced object implements IDisposable, and you do this typically to release unmanaged resources - though there may be other reasons why a class implements this interface.
Your first method is total overkill... it should just be as described in MySecondFunction(), and just don't swallow exceptions (I'm referring to the empty catch block) like that - because it leads to buggy, unmaintanable code! :)

Should Dispose() ever create new instances of objects?

Using C#.NET 4.0
My company's application makes use of a resource locker to keep records from being edited simultaneously. We use the database to store the start time of a lock as well as the user who acquired the lock. This has led to the following (strange?) implementation of dispose on the resource locker, which happens to be called from a destructor:
protected virtual void Dispose(bool disposing)
{
lock (this)
{
if (lockid.HasValue)
{
this.RefreshDataButtonAction = null;
this.ReadOnlyButtonAction = null;
try
{
**Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("#lockID", lockid.Value);
parameters.Add("#readsToDelete", null);
Object returnObject = dbio2.ExecuteScalar("usp_DeleteResourceLockReads", parameters);**
lockid = null;
}
catch (Exception ex)
{
Logger.WriteError("ResourceLockingController", "DeleteResourceLocks", ex);
}
finally
{
((IDisposable)_staleResourcesForm).Dispose();
_staleResourcesForm = null;
}
}
}
}
I am concerned about the bolded section we because have been logging strange "Handle is not initialized" exceptions from the database call. I read elsewhere that it is not safe to create new objects during Finalize(), but does the same rule apply to dispose()? Are there any possible side effects that accompany creating new objects during Dispose()?
which happens to be called from a destructor
That's the real problem. You cannot assume that the *dbio2" object hasn't been finalized itself. Finalization order is not deterministic in .NET. The outcome would look much like you describe, an internal handle used by the dbase provider will have been released so a "Handle is not initialized" exception is expected. Or the dbio2 object was simply already disposed.
This is especially likely to go wrong at program exit. You'll then also have problem when the 2 second timeout for the finalizer thread, a dbase operation can easily take more.
You simply cannot rely on a finalizer to do this for you. You must check the disposing argument and not call the dbio2.ExecuteScalar() method when it is false. Which probably ends the usefulness of the destructor as well.
Dispose is just a method, like any other method. There are some conventions about things that it should/shouldn't do, but there's nothing from the system's perspective that is wrong with creating objects in a Dispose call.
Making a DB call is a bit concerning to be personally; I wouldn't expect such an expensive and error prone activity to be called in a Dispose method, but that's more of a convention/expectation. The system won't have a problem with that.
Yes, but I would not do so unless the object created is within the local scope of the method. IDisposable is an advertisement that this class has some resource (often an unmanaged resource) that should be freed when the object is no longer used. If your Dispose is being called by your finializer (ie you are not calling the destructor directly, but waiting for the GC to do it) it can be an indication that you should be calling it earlier. You never know when the C# destructor will run, so you may be unnecessarily tying up that resource. It could also be in indication that your class doesn't need to implement IDisposable.
In your case your are using object dbio2 which I assume represents your DB connection. However, since this is called from the destructor how do you know if your connection is still valid? You destructor could an hour after your connection has been lost. You should try to ensure that this Dispose is called while you know the dbio2 object is still in scope.

Variables with function scope

How the CLR handles local variables with function scope in case an exception is thrown.
is it a must to use the finally block or the variable is disposed once the flow leaves the function
below is a small example
protected void FunctionX()
{
List<Employee> lstEmployees;
try
{
lstEmployees= new List<Employee>();
int s = lstEmployees[1].ID; // code intended to throw exception
}
catch (Exception ex)
{
ManageException(ex, ShowMessage); //exception is thrown here
}
finally { lstEmployees= null; } // Is the finally block required to make sure the list is cleaned
}
To answer your specific question, no, the finally block you've listed is not required.
Assigning null to a reference variable does not actually do anything, as garbage collection is non-deterministic. As a simplistic explanation, from time to time, the garbage collector will examine the objects within the heap to determine if there are any active references to them (this is called being "rooted"). If there are no active references, then these references are eligible for garbage collection.
Your assignment to null is not required, as once the function exits, the lstEmployees variable will fall out of scope and will no longer be considered an active reference to the instance that you create within your try block.
There are certain types (both within .NET and in third-party libraries) that implement the IDisposable interface and expose some deterministic cleanup procedures through the Dispose() function. When using these types, you should always call Dispose() when you're finished with the type. In cases where the lifetime of the instance shouldn't extend outside of the lifetime of the function, then you can use a using() { } block, but this is only required if the type implements IDisposable, which List<T> (as you used in your example) does not.
Don't be worried about the objects cleanup, that's why the .NET and most modern languages provide the garbage collection functionality in runtime.
If your object has a handle to unmanaged resource do that cleanup.
Some of the other answers are slightly misleading here.
In fact, the garbage collector has got (almost) nothing to do with the variable lstEmployees. But it never needs to be set to null, neither in normal code flow nor after an exception is thrown.
Setting references to null to free the object they point they point to is almost never required, especially not for local objects.
As a consequence, the garbage collector won’t care about the exception either.
On the other hand, unmanaged resources which aren’t handled by the CG do always require manual cleanup (via the Dispose method of the IDisposable interface). To make sure that such resources are returned after an exception was thrown, you indeed need the finally clause. Or, if you don’t intend to handle the exception locally, you can replace the try … finally by a using clause:
using (someUnmanagedResource) {
// … use the resource …
}
// Will implicitly call someUnmanagedResource.Dispose() *whatever happens*!
.NET languages are garbage collected, which means that objects lifetimes are kept track of, so the garbage collection will get rid of your list when it finds no more object references to it.
Not at all. When the variable is out of scope, the garbage collector will take care of it (when the GC decides it's time to collect all the garbage...)
The only thing you have to take in account is that maybe you don't want to wait for the GC to do its job, so resources help by an instance of a class are released (e.g. imagine you have locally created an instance that hols a reference to a database connection. The connection will be held until GC takes care of deleting the instance, and later on deleting the referenced connection, which may take a while).
In these cases, take a look at the IDisposable interface, so you can proactively free resources before your instances are removed by the GC.
.NET's garbage collector will handle this for you. In fact, setting "lastEmployees" to null accomplishes the same thing as just exiting the function.
Any item that is no longer referenced by the root application in one form or another will be marked for collection.
In .NET, you never need to worry about cleaning up managed resource. Hence, managed.
http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx

Should a .Net/C# object call Dispose() on itself?

Below is some sample code written by a colleague. This seems obviously wrong to me but I wanted to check. Should an object call its own Dispose() method from within one of its own methods? It seems to me that only the owner/creator of the object should call Dispose() when it's done with the object and not the object itself.
It's an .asmx web method that calls Dispose() on itself when it's done. (The fact that it's a web method is probably incidental to the question in general.) In our code base we sometimes instantiate web service classes within methods of other web services and then call methods on them. If my code does that to call this method, the object is toast when the method returns and I can't really use the object any more.
[WebMethod]
public string MyWebMethod()
{
try
{
return doSomething();
}
catch(Exception exception)
{
return string.Empty;
}
finally
{
Dispose(true);
}
}
UPDATE:
Found a few links that are related:
Do I need to dispose a web service reference in ASP.NET?
Dispose a Web Service Proxy class?
For sure it's not a good prartice. The caller should decide when he is finished using the IDisposable object, not an object itself.
There are very few valid reasons to perform a "Self Disposing" action.
Threading is the one I use more than not.
I have several applications that "fire and forget" threads.
Using this methodology allow the object to self dispose.
This helps keep the environment clean without a threading manager process.
if I ever see that in one of my projects, I would ask why and I'm 99.9999% sure that i would remove it anyway
for me this is a kind of red flag / code smells
There are no technical restrictions on what a Dispose method is allowed to do. The only thing special about it is that Dispose gets called in certain constructs (foreach, using). Because of that, Dispose might reasonably be used to flag an object as no-longer-useable, especially if the call is idempotent.
I would not use it for this purpose however, because of the accepted semantics of Dispose. If I wanted to mark an object as no-longer-useable from within the class itself, then I would create a MarkUnuseable() method that could be called by Dispose or any other place.
By restricting the calls to Dispose to the commonly accepted patterns, you buy the ability to make changes to the Dispose methods in all of your classes with confidence that you will not unexpectedly break any code that deviates from the common pattern.
Just remove it, but take care to dispose it in all object that call it.
Technically yes, if that "method" is the finaliser and you are implementing the Finalise and IDisposable pattern as specified by Microsoft.
While a .Net object would not normally call Dispose on itself, there are times when code running within an object may be the last thing that expects to be using it. As a simple example, if a Dispose method can handle the cleanup of a partially-constructed object, it may be useful to have a constructor coded something like the following:
Sub New()
Dim OK As Boolean = False
Try
... do Stuff
OK = True
Finally
If Not OK Then Me.Dispose
End Try
End Sub
If the constructor is going to throw an exception without returning, then the partially-constructed object, which is slated for abandonment, will be the only thing that will ever have the information and impetus to do the necessary cleanup. If it doesn't take care of ensuring a timely Dispose, nothing else will.
With regard to your particular piece of code, the pattern is somewhat unusual, but it looks somewhat like the way a socket can get passed from one thread to another. There's a call which returns an array of bytes and invalidates a Socket; that array of bytes can be used in another thread to create a new Socket instance which takes over the communications stream established by the other Socket. Note that the data regarding the open socket is effectively an unmanaged resource, but it can't very well be wrapped in an object with a finalizer because it's often going to be handed off to something the garbage-collector can't see.
No! It is unexpected behavior and breaks the best practices guidelines. Never do anything that is unexpeceted. Your object should only do what is needed to maintain it's state while protecting the integrity of the object for the caller. The caller will decide when it's done (or the GC if nothing else).

Using Dispose on a Singleton to Cleanup Resources

The question I have might be more to do with semantics than with the actual use of IDisposable. I am working on implementing a singleton class that is in charge of managing a database instance that is created during the execution of the application. When the application closes this database should be deleted.
Right now I have this delete being handled by a Cleanup() method of the singleton that the application calls when it is closing. As I was writing the documentation for Cleanup() it struck me that I was describing what a Dispose() method should be used for i.e. cleaning up resources. I had originally not implemented IDisposable because it seemed out of place in my singleton, because I didn't want anything to dispose the singleton itself. There isn't currently, but in the future might be a reason that this Cleanup() might be called but the singleton should will need to still exist. I think I can include GC.SuppressFinalize(this); in the Dispose method to make this feasible.
My question therefore is multi-parted:
1) Is implementing IDisposable on a singleton fundamentally a bad idea?
2) Am I just mixing semantics here by having a Cleanup() instead of a Dispose() and since I'm disposing resources I really should use a dispose?
3) Will implementing 'Dispose()' with GC.SuppressFinalize(this); make it so my singleton is not actually destroyed in the case I want it to live after a call to clean-up the database.
Implementing IDisposable for singleton might be good idea if you use a CAS techinque instead of locks to create a singleton. Something like this.
if (instance == null) {
var temp = new Singleton();
if (Interlocked.CompareExchange(ref instance, temp, null) != null) &&
temp is IDisposable) {
((IDisposable)temp).Dispose();
}
}
return instance
We created a temporary object and tried atomic Compare-and-Swap so we need to dispose this temporary object if it impletents IDisposable and it wasn't written to instance's location.
It might be good to avoid locks but also it's a bit overhead if some heavy logic is used to create a singleton's instance in its constructor.
If you don't want other code to cleanup or dispose your object just don't provide any opportunity for this. However, it might be good idea to provide some kind of reset() method to allow singleton to recreate itself if, let say, you use a lazy init. Something like this:
public static Singletong GetInstance() {
if (instance == null) {
instance = new Singleton(); //here we re-evalute cache for example
}
return instance
}
public static void Reset() {
instance = null;
}
In short, if you have a singleton and you call dispose. Any time that any object tries to use it after that, will be using an object in a disposed state.
Now putting it in, and disposing of the object after the application is done with it, isn't necessarily bad. You do have to be careful though when you call it. If you are really concerned with the cleanup and you have only one reference to it, you can put the clean up code in the objects finalizer ~YourClass that way it will only be called with .Net is sure it is no longer needed (when the application closes, if it is a true singleton).
Am I just mixing semantics here by
having a Cleanup() instead of a
Dispose() and since I'm disposing
resources I really should use a
dispose?
Yes, this is just semantics. Dispose is the standard for showing there are things that need to be cleared up after the program is done with the object.
Will implementing 'Dispose()' with
GC.SuppressFinalize(this); make it so
my singleton is not actually destroyed
in the case I want it to live after a
call to clean-up the database.
No what this means is that when you call the dispose method, the Garbage Collector won't call the object's custom finalizer.
I agree with Kevin's answer, but like to add something to this. I'm a bit confused about your statement:
When the application closes this
database should be deleted.
Do you really mean deleted? As in destroyed? Are you talking about a real (SQL) database?
You must understand that even if you put your clean up code in a finalizer, or in the Application_End event (ASP.NET) there is no way you can guarantee these are called. The process can be terminated, or the computer loses power. It seems more reasonable to delete the database on application startup, or at least have a fallback mechanism at startup with some cleanup.
While the finalizer would be a good place to put cleanup when dealing with resources, in your case we're talking about an application resource. What I mean by this is that the resource isn't perhaps bound to a single object (your singleton) but is part of the whole application. This can get a bit an abstract discussion, and it's perhaps more a matter of view.
What I'm trying to say it that when you see that database as a application resource, you will have to have your initialization and cleanup not bound to an object, but to the application. In an ASP.NET application this would be Application_Start and Application_End (global.asax). In an Windows Forms application, this would be Program.Main.
Still, when using these mechanisms over finalizers, you have no certainty that your clean up code will execute.

Categories

Resources