implementing Dispose and Finalize for Windows phone silverlight Pages - c#

I have a big solution with graphics, popups and animations. I have found out that I have a massive memory leak during page navigations.
Tries
I therefore tried with the first solution:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (App.RootFrame.CanGoBack)
App.RootFrame.RemoveBackEntry();
GC.Collect();
base.OnNavigatedTo(e);
}
This from several sources on MSDN and Stackoverflow, should remove the memory stored for the page. This was not the case and I am unsure if the MVVM structure of the code somehow keeps information stored. I then tried to implement deconstructors and force values to null when the event was fired like:
~SecondScreen()
{
In_Game_Crest = null;
currentViewModel = null;
}
This I did for all pages, popups and usercontrols. I then again went through the code using debug, and non of the pages deconstructor was ever fired. This has lead me on to try and use IDisposable and fiddeling around with the viewmodelLocator provided by MVVMLight, without any success.
Investigation
I have read the following addressing the issue:
StackOverFlow: Finalizer and Dispose
Finalize/Dispose pattern in C#
MSDN: Implementing a Dispose Method
MSDN: Implementing Finalize and Dispose to Clean Up Unmanaged Resources
Questions
But it has confused me more than it helped me. How should I implement the dispose and finalize methods for a page for my windows phone?
Since I'm using the MVVM structure should these methods be implemented in a ViewModel or behind the given page or both?
Examples for windows phones would be much appreciated.
Initial try with Dispose
I have read some more about the subject and found that the finalize maybe shouldn't be written? But I am still unsure. But based on this and the first MSDN link above, I tried the following:
private bool disposed = false;
public void Dispose()
{
Dispose(true);
// Take yourself off the Finalization queue
// to prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
currentView = null;
popup = null;
Image1 = null;
Image2 = null;
}
// Release unmanaged resources. If disposing is false,
// only the following code is executed.
this.Content = null;
// Note that this is not thread safe.
// Another thread could start disposing the object
// after the managed resources are disposed,
// but before the disposed flag is set to true.
// If thread safety is necessary, it must be
// implemented by the client.
}
disposed = true;
}
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~FirstPage()
{
Dispose(false);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
this.Dispose();
base.OnNavigatedFrom(e);
}
But, but but this just made my memory increase by 23MB when I got to the second screen. This leads me to the question again, how and what should I try to implement, and WHY could the memory increase?
this = null, base.Dispose()
I have seen different implementations, either using this = null in the dispose function or using base.Dispose(). I figure that the latter can only be used if the class is IDisposable? Is this the way to go? If so how do I go about it?
Using Microsoft Profiler
So I used the profiler to verify that the FirstPage is not removed
From the above Figure it can be seen that the firstpage exists. In the comments I was told to look for the instances and reference to the elements. I therefore chose instances of firstpage and got:
Here it is confirmed that FirstPage is never destroyed. But I am stuck here, how should I interpret the data?
Hoping for some help.

It is not actually necessary to dispose when a user navigates away from a page, the performance implications of creating objects all over again is more than the memory load of having a page in the memory during when the application is alive.
You should take a decision between removing objects from the memory vis.a.vis recreating the same set of objects again.
Having said this you should be careful with the navigation model.
Memory problems might occur if you are creating objects every time the user is navigating to a page but not actually disposing when the user navigates away.
For this purpose I recommend fully understanding the PageBase and NavigationHelper or NavigationService class in your application.
You have mentioned that FirstPage is not removed from the memory during the life time of the app which according to me is ideal.
Place debug points in the potential places in your code where heavy objects might get created;
navigate a couple of times to different Pages, then come back.
Check the behavior then you might get a clear picture for yourself.
For all objects check that you manually invoke Dispose.
Dispose is a completely different concept than GarbageCollector, Dispose is just an contract that developers should adhere to by invoking it for releasing resources they perceive are no longer required to be maintained in the memory since garbage collection by the platform takes place at a indeterminate time.
In the sample you have posted I see that you are setting objects to null without actually disposing. Setting to null just changes the memory location that variable is pointing to.
It does not destroy the object immediately. an ideal dispose should be like below.
//Call on OnClosing or OnExit or similar context
protected override void Dispose(bool isDisposing)
{
if(isDisposing && !_isDisposed){
if(disposeableImage != null){
disposeableImage.Dispose();
disposeableImage = null;
}
}
}

So what I did to solve the page memory leak was using the answer at this question:
Remove Pages windows phone
There still exists some leak, which helped when removing the storyboards and eventhandlers, and adding them and removing them. But some memory is still there but no leak is occurring.

Related

C# dispose unmanaged object stored in managed collection [duplicate]

I know from reading Microsoft documentation that the "primary" use of the IDisposable interface is to clean up unmanaged resources.
To me, "unmanaged" means things like database connections, sockets, window handles, etc. But, I've seen code where the Dispose() method is implemented to free managed resources, which seems redundant to me, since the garbage collector should take care of that for you.
For example:
public class MyCollection : IDisposable
{
private List<String> _theList = new List<String>();
private Dictionary<String, Point> _theDict = new Dictionary<String, Point>();
// Die, clear it up! (free unmanaged resources)
public void Dispose()
{
_theList.clear();
_theDict.clear();
_theList = null;
_theDict = null;
}
}
My question is, does this make the garbage collector free memory used by MyCollection any faster than it normally would?
Edit: So far people have posted some good examples of using IDisposable to clean up unmanaged resources such as database connections and bitmaps. But suppose that _theList in the above code contained a million strings, and you wanted to free that memory now, rather than waiting for the garbage collector. Would the above code accomplish that?
The point of Dispose is to free unmanaged resources. It needs to be done at some point, otherwise they will never be cleaned up. The garbage collector doesn't know how to call DeleteHandle() on a variable of type IntPtr, it doesn't know whether or not it needs to call DeleteHandle().
Note: What is an unmanaged resource? If you found it in the Microsoft .NET Framework: it's managed. If you went poking around MSDN yourself, it's unmanaged. Anything you've used P/Invoke calls to get outside of the nice comfy world of everything available to you in the .NET Framework is unmanaged – and you're now responsible for cleaning it up.
The object that you've created needs to expose some method, that the outside world can call, in order to clean up unmanaged resources. The method can be named whatever you like:
public void Cleanup()
or
public void Shutdown()
But instead there is a standardized name for this method:
public void Dispose()
There was even an interface created, IDisposable, that has just that one method:
public interface IDisposable
{
void Dispose()
}
So you make your object expose the IDisposable interface, and that way you promise that you've written that single method to clean up your unmanaged resources:
public void Dispose()
{
Win32.DestroyHandle(this.CursorFileBitmapIconServiceHandle);
}
And you're done. Except you can do better.
What if your object has allocated a 250MB System.Drawing.Bitmap (i.e. the .NET managed Bitmap class) as some sort of frame buffer? Sure, this is a managed .NET object, and the garbage collector will free it. But do you really want to leave 250MB of memory just sitting there – waiting for the garbage collector to eventually come along and free it? What if there's an open database connection? Surely we don't want that connection sitting open, waiting for the GC to finalize the object.
If the user has called Dispose() (meaning they no longer plan to use the object) why not get rid of those wasteful bitmaps and database connections?
So now we will:
get rid of unmanaged resources (because we have to), and
get rid of managed resources (because we want to be helpful)
So let's update our Dispose() method to get rid of those managed objects:
public void Dispose()
{
//Free unmanaged resources
Win32.DestroyHandle(this.CursorFileBitmapIconServiceHandle);
//Free managed resources too
if (this.databaseConnection != null)
{
this.databaseConnection.Dispose();
this.databaseConnection = null;
}
if (this.frameBufferImage != null)
{
this.frameBufferImage.Dispose();
this.frameBufferImage = null;
}
}
And all is good, except you can do better!
What if the person forgot to call Dispose() on your object? Then they would leak some unmanaged resources!
Note: They won't leak managed resources, because eventually the garbage collector is going to run, on a background thread, and free the memory associated with any unused objects. This will include your object, and any managed objects you use (e.g. the Bitmap and the DbConnection).
If the person forgot to call Dispose(), we can still save their bacon! We still have a way to call it for them: when the garbage collector finally gets around to freeing (i.e. finalizing) our object.
Note: The garbage collector will eventually free all managed objects.
When it does, it calls the Finalize
method on the object. The GC doesn't know, or
care, about your Dispose method.
That was just a name we chose for
a method we call when we want to get
rid of unmanaged stuff.
The destruction of our object by the Garbage collector is the perfect time to free those pesky unmanaged resources. We do this by overriding the Finalize() method.
Note: In C#, you don't explicitly override the Finalize() method.
You write a method that looks like a C++ destructor, and the
compiler takes that to be your implementation of the Finalize() method:
~MyObject()
{
//we're being finalized (i.e. destroyed), call Dispose in case the user forgot to
Dispose(); //<--Warning: subtle bug! Keep reading!
}
But there's a bug in that code. You see, the garbage collector runs on a background thread; you don't know the order in which two objects are destroyed. It is entirely possible that in your Dispose() code, the managed object you're trying to get rid of (because you wanted to be helpful) is no longer there:
public void Dispose()
{
//Free unmanaged resources
Win32.DestroyHandle(this.gdiCursorBitmapStreamFileHandle);
//Free managed resources too
if (this.databaseConnection != null)
{
this.databaseConnection.Dispose(); //<-- crash, GC already destroyed it
this.databaseConnection = null;
}
if (this.frameBufferImage != null)
{
this.frameBufferImage.Dispose(); //<-- crash, GC already destroyed it
this.frameBufferImage = null;
}
}
So what you need is a way for Finalize() to tell Dispose() that it should not touch any managed resources (because they might not be there anymore), while still freeing unmanaged resources.
The standard pattern to do this is to have Finalize() and Dispose() both call a third(!) method; where you pass a Boolean saying if you're calling it from Dispose() (as opposed to Finalize()), meaning it's safe to free managed resources.
This internal method could be given some arbitrary name like "CoreDispose", or "MyInternalDispose", but is tradition to call it Dispose(Boolean):
protected void Dispose(Boolean disposing)
But a more helpful parameter name might be:
protected void Dispose(Boolean itIsSafeToAlsoFreeManagedObjects)
{
//Free unmanaged resources
Win32.DestroyHandle(this.CursorFileBitmapIconServiceHandle);
//Free managed resources too, but only if I'm being called from Dispose
//(If I'm being called from Finalize then the objects might not exist
//anymore
if (itIsSafeToAlsoFreeManagedObjects)
{
if (this.databaseConnection != null)
{
this.databaseConnection.Dispose();
this.databaseConnection = null;
}
if (this.frameBufferImage != null)
{
this.frameBufferImage.Dispose();
this.frameBufferImage = null;
}
}
}
And you change your implementation of the IDisposable.Dispose() method to:
public void Dispose()
{
Dispose(true); //I am calling you from Dispose, it's safe
}
and your finalizer to:
~MyObject()
{
Dispose(false); //I am *not* calling you from Dispose, it's *not* safe
}
Note: If your object descends from an object that implements Dispose, then don't forget to call their base Dispose method when you override Dispose:
public override void Dispose()
{
try
{
Dispose(true); //true: safe to free managed resources
}
finally
{
base.Dispose();
}
}
And all is good, except you can do better!
If the user calls Dispose() on your object, then everything has been cleaned up. Later on, when the garbage collector comes along and calls Finalize, it will then call Dispose again.
Not only is this wasteful, but if your object has junk references to objects you already disposed of from the last call to Dispose(), you'll try to dispose them again!
You'll notice in my code I was careful to remove references to objects that I've disposed, so I don't try to call Dispose on a junk object reference. But that didn't stop a subtle bug from creeping in.
When the user calls Dispose(): the handle CursorFileBitmapIconServiceHandle is destroyed. Later when the garbage collector runs, it will try to destroy the same handle again.
protected void Dispose(Boolean iAmBeingCalledFromDisposeAndNotFinalize)
{
//Free unmanaged resources
Win32.DestroyHandle(this.CursorFileBitmapIconServiceHandle); //<--double destroy
...
}
The way you fix this is tell the garbage collector that it doesn't need to bother finalizing the object – its resources have already been cleaned up, and no more work is needed. You do this by calling GC.SuppressFinalize() in the Dispose() method:
public void Dispose()
{
Dispose(true); //I am calling you from Dispose, it's safe
GC.SuppressFinalize(this); //Hey, GC: don't bother calling finalize later
}
Now that the user has called Dispose(), we have:
freed unmanaged resources
freed managed resources
There's no point in the GC running the finalizer – everything's taken care of.
Couldn't I use Finalize to cleanup unmanaged resources?
The documentation for Object.Finalize says:
The Finalize method is used to perform cleanup operations on unmanaged resources held by the current object before the object is destroyed.
But the MSDN documentation also says, for IDisposable.Dispose:
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
So which is it? Which one is the place for me to cleanup unmanaged resources? The answer is:
It's your choice! But choose Dispose.
You certainly could place your unmanaged cleanup in the finalizer:
~MyObject()
{
//Free unmanaged resources
Win32.DestroyHandle(this.CursorFileBitmapIconServiceHandle);
//A C# destructor automatically calls the destructor of its base class.
}
The problem with that is you have no idea when the garbage collector will get around to finalizing your object. Your un-managed, un-needed, un-used native resources will stick around until the garbage collector eventually runs. Then it will call your finalizer method; cleaning up unmanaged resources. The documentation of Object.Finalize points this out:
The exact time when the finalizer executes is undefined. To ensure deterministic release of resources for instances of your class, implement a Close method or provide a IDisposable.Dispose implementation.
This is the virtue of using Dispose to cleanup unmanaged resources; you get to know, and control, when unmanaged resource are cleaned up. Their destruction is "deterministic".
To answer your original question: Why not release memory now, rather than for when the GC decides to do it? I have a facial recognition software that needs to get rid of 530 MB of internal images now, since they're no longer needed. When we don't: the machine grinds to a swapping halt.
Bonus Reading
For anyone who likes the style of this answer (explaining the why, so the how becomes obvious), I suggest you read Chapter One of Don Box's Essential COM:
Direct link: Chapter 1 sample by Pearson Publishing
magnet: 84bf0b960936d677190a2be355858e80ef7542c0
In 35 pages he explains the problems of using binary objects, and invents COM before your eyes. Once you realize the why of COM, the remaining 300 pages are obvious, and just detail Microsoft's implementation.
I think every programmer who has ever dealt with objects or COM should, at the very least, read the first chapter. It is the best explanation of anything ever.
Extra Bonus Reading
When everything you know is wrong archiveby Eric Lippert
It is therefore very difficult indeed to write a correct finalizer,
and the best advice I can give you is to not try.
IDisposable is often used to exploit the using statement and take advantage of an easy way to do deterministic cleanup of managed objects.
public class LoggingContext : IDisposable {
public Finicky(string name) {
Log.Write("Entering Log Context {0}", name);
Log.Indent();
}
public void Dispose() {
Log.Outdent();
}
public static void Main() {
Log.Write("Some initial stuff.");
try {
using(new LoggingContext()) {
Log.Write("Some stuff inside the context.");
throw new Exception();
}
} catch {
Log.Write("Man, that was a heavy exception caught from inside a child logging context!");
} finally {
Log.Write("Some final stuff.");
}
}
}
The purpose of the Dispose pattern is to provide a mechanism to clean up both managed and unmanaged resources and when that occurs depends on how the Dispose method is being called. In your example, the use of Dispose is not actually doing anything related to dispose, since clearing a list has no impact on that collection being disposed. Likewise, the calls to set the variables to null also have no impact on the GC.
You can take a look at this article for more details on how to implement the Dispose pattern, but it basically looks like this:
public class SimpleCleanup : IDisposable
{
// some fields that require cleanup
private SafeHandle handle;
private bool disposed = false; // to detect redundant calls
public SimpleCleanup()
{
this.handle = /*...*/;
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Dispose managed resources.
if (handle != null)
{
handle.Dispose();
}
}
// Dispose unmanaged managed resources.
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
The method that is the most important here is the Dispose(bool), which actually runs under two different circumstances:
disposing == true: the method has been called directly or indirectly by a user's code. Managed and unmanaged resources can be disposed.
disposing == false: the method has been called by the runtime from inside the finalizer, and you should not reference other objects. Only unmanaged resources can be disposed.
The problem with simply letting the GC take care of doing the cleanup is that you have no real control over when the GC will run a collection cycle (you can call GC.Collect(), but you really shouldn't) so resources may stay around longer than needed. Remember, calling Dispose() doesn't actually cause a collection cycle or in any way cause the GC to collect/free the object; it simply provides the means to more deterministicly cleanup the resources used and tell the GC that this cleanup has already been performed.
The whole point of IDisposable and the dispose pattern isn't about immediately freeing memory. The only time a call to Dispose will actually even have a chance of immediately freeing memory is when it is handling the disposing == false scenario and manipulating unmanaged resources. For managed code, the memory won't actually be reclaimed until the GC runs a collection cycle, which you really have no control over (other than calling GC.Collect(), which I've already mentioned is not a good idea).
Your scenario isn't really valid since strings in .NET don't use any unamanged resources and don't implement IDisposable, there is no way to force them to be "cleaned up."
There should be no further calls to an object's methods after Dispose has been called on it (although an object should tolerate further calls to Dispose). Therefore the example in the question is silly. If Dispose is called, then the object itself can be discarded. So the user should just discard all references to that whole object (set them to null) and all the related objects internal to it will automatically get cleaned up.
As for the general question about managed/unmanaged and the discussion in other answers, I think any answer to this question has to start with a definition of an unmanaged resource.
What it boils down to is that there is a function you can call to put the system into a state, and there's another function you can call to bring it back out of that state. Now, in the typical example, the first one might be a function that returns a file handle, and the second one might be a call to CloseHandle.
But - and this is the key - they could be any matching pair of functions. One builds up a state, the other tears it down. If the state has been built but not torn down yet, then an instance of the resource exists. You have to arrange for the teardown to happen at the right time - the resource is not managed by the CLR. The only automatically managed resource type is memory. There are two kinds: the GC, and the stack. Value types are managed by the stack (or by hitching a ride inside reference types), and reference types are managed by the GC.
These functions may cause state changes that can be freely interleaved, or may need to be perfectly nested. The state changes may be threadsafe, or they might not.
Look at the example in Justice's question. Changes to the Log file's indentation must be perfectly nested, or it all goes wrong. Also they are unlikely to be threadsafe.
It is possible to hitch a ride with the garbage collector to get your unmanaged resources cleaned up. But only if the state change functions are threadsafe and two states can have lifetimes that overlap in any way. So Justice's example of a resource must NOT have a finalizer! It just wouldn't help anyone.
For those kinds of resources, you can just implement IDisposable, without a finalizer. The finalizer is absolutely optional - it has to be. This is glossed over or not even mentioned in many books.
You then have to use the using statement to have any chance of ensuring that Dispose is called. This is essentially like hitching a ride with the stack (so as finalizer is to the GC, using is to the stack).
The missing part is that you have to manually write Dispose and make it call onto your fields and your base class. C++/CLI programmers don't have to do that. The compiler writes it for them in most cases.
There is an alternative, which I prefer for states that nest perfectly and are not threadsafe (apart from anything else, avoiding IDisposable spares you the problem of having an argument with someone who can't resist adding a finalizer to every class that implements IDisposable).
Instead of writing a class, you write a function. The function accepts a delegate to call back to:
public static void Indented(this Log log, Action action)
{
log.Indent();
try
{
action();
}
finally
{
log.Outdent();
}
}
And then a simple example would be:
Log.Write("Message at the top");
Log.Indented(() =>
{
Log.Write("And this is indented");
Log.Indented(() =>
{
Log.Write("This is even more indented");
});
});
Log.Write("Back at the outermost level again");
The lambda being passed in serves as a code block, so it's like you make your own control structure to serve the same purpose as using, except that you no longer have any danger of the caller abusing it. There's no way they can fail to clean up the resource.
This technique is less useful if the resource is the kind that may have overlapping lifetimes, because then you want to be able to build resource A, then resource B, then kill resource A and then later kill resource B. You can't do that if you've forced the user to perfectly nest like this. But then you need to use IDisposable (but still without a finalizer, unless you have implemented threadsafety, which isn't free).
Scenarios I make use of IDisposable: clean up unmanaged resources, unsubscribe for events, close connections
The idiom I use for implementing IDisposable (not threadsafe):
class MyClass : IDisposable {
// ...
#region IDisposable Members and Helpers
private bool disposed = false;
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing) {
if (!this.disposed) {
if (disposing) {
// cleanup code goes here
}
disposed = true;
}
}
~MyClass() {
Dispose(false);
}
#endregion
}
Yep, that code is completely redundant and unnecessary and it doesn't make the garbage collector do anything it wouldn't otherwise do (once an instance of MyCollection goes out of scope, that is.) Especially the .Clear() calls.
Answer to your edit: Sort of. If I do this:
public void WasteMemory()
{
var instance = new MyCollection(); // this one has no Dispose() method
instance.FillItWithAMillionStrings();
}
// 1 million strings are in memory, but marked for reclamation by the GC
It's functionally identical to this for purposes of memory management:
public void WasteMemory()
{
var instance = new MyCollection(); // this one has your Dispose()
instance.FillItWithAMillionStrings();
instance.Dispose();
}
// 1 million strings are in memory, but marked for reclamation by the GC
If you really really really need to free the memory this very instant, call GC.Collect(). There's no reason to do this here, though. The memory will be freed when it's needed.
If MyCollection is going to be garbage collected anyway, then you shouldn't need to dispose it. Doing so will just churn the CPU more than necessary, and may even invalidate some pre-calculated analysis that the garbage collector has already performed.
I use IDisposable to do things like ensure threads are disposed correctly, along with unmanaged resources.
EDIT In response to Scott's comment:
The only time the GC performance metrics are affected is when a call the [sic] GC.Collect() is made"
Conceptually, the GC maintains a view of the object reference graph, and all references to it from the stack frames of threads. This heap can be quite large and span many pages of memory. As an optimisation, the GC caches its analysis of pages that are unlikely to change very often to avoid rescanning the page unnecessarily. The GC receives notification from the kernel when data in a page changes, so it knows that the page is dirty and requires a rescan. If the collection is in Gen0 then it's likely that other things in the page are changing too, but this is less likely in Gen1 and Gen2. Anecdotally, these hooks were not available in Mac OS X for the team who ported the GC to Mac in order to get the Silverlight plug-in working on that platform.
Another point against unnecessary disposal of resources: imagine a situation where a process is unloading. Imagine also that the process has been running for some time. Chances are that many of that process's memory pages have been swapped to disk. At the very least they're no longer in L1 or L2 cache. In such a situation there is no point for an application that's unloading to swap all those data and code pages back into memory to 'release' resources that are going to be released by the operating system anyway when the process terminates. This applies to managed and even certain unmanaged resources. Only resources that keep non-background threads alive must be disposed, otherwise the process will remain alive.
Now, during normal execution there are ephemeral resources that must be cleaned up correctly (as #fezmonkey points out database connections, sockets, window handles) to avoid unmanaged memory leaks. These are the kinds of things that have to be disposed. If you create some class that owns a thread (and by owns I mean that it created it and therefore is responsible for ensuring it stops, at least by my coding style), then that class most likely must implement IDisposable and tear down the thread during Dispose.
The .NET framework uses the IDisposable interface as a signal, even warning, to developers that the this class must be disposed. I can't think of any types in the framework that implement IDisposable (excluding explicit interface implementations) where disposal is optional.
I won't repeat the usual stuff about Using or freeing un-managed resources, that has all been covered. But I would like to point out what seems a common misconception.
Given the following code
Public Class LargeStuff
Implements IDisposable
Private _Large as string()
'Some strange code that means _Large now contains several million long strings.
Public Sub Dispose() Implements IDisposable.Dispose
_Large=Nothing
End Sub
I realise that the Disposable implementation does not follow current guidelines, but hopefully you all get the idea.
Now, when Dispose is called, how much memory gets freed?
Answer: None.
Calling Dispose can release unmanaged resources, it CANNOT reclaim managed memory, only the GC can do that. Thats not to say that the above isn't a good idea, following the above pattern is still a good idea in fact. Once Dispose has been run, there is nothing stopping the GC re-claiming the memory that was being used by _Large, even though the instance of LargeStuff may still be in scope. The strings in _Large may also be in gen 0 but the instance of LargeStuff might be gen 2, so again, memory would be re-claimed sooner.
There is no point in adding a finaliser to call the Dispose method shown above though. That will just DELAY the re-claiming of memory to allow the finaliser to run.
In the example you posted, it still doesn't "free the memory now". All memory is garbage collected, but it may allow the memory to be collected in an earlier generation. You'd have to run some tests to be sure.
The Framework Design Guidelines are guidelines, and not rules. They tell you what the interface is primarily for, when to use it, how to use it, and when not to use it.
I once read code that was a simple RollBack() on failure utilizing IDisposable. The MiniTx class below would check a flag on Dispose() and if the Commit call never happened it would then call Rollback on itself. It added a layer of indirection making the calling code a lot easier to understand and maintain. The result looked something like:
using( MiniTx tx = new MiniTx() )
{
// code that might not work.
tx.Commit();
}
I've also seen timing / logging code do the same thing. In this case the Dispose() method stopped the timer and logged that the block had exited.
using( LogTimer log = new LogTimer("MyCategory", "Some message") )
{
// code to time...
}
So here are a couple of concrete examples that don't do any unmanaged resource cleanup, but do successfully used IDisposable to create cleaner code.
If you want to delete right now, use unmanaged memory.
See:
Marshal.AllocHGlobal
Marshal.FreeHGlobal
Marshal.DestroyStructure
If anything, I'd expect the code to be less efficient than when leaving it out.
Calling the Clear() methods are unnecessary, and the GC probably wouldn't do that if the Dispose didn't do it...
Apart from its primary use as a way to control the lifetime of system resources (completely covered by the awesome answer of Ian, kudos!), the IDisposable/using combo can also be used to scope the state change of (critical) global resources: the console, the threads, the process, any global object like an application instance.
I've written an article about this pattern: http://pragmateek.com/c-scope-your-global-state-changes-with-idisposable-and-the-using-statement/
It illustrates how you can protect some often used global state in a reusable and readable manner: console colors, current thread culture, Excel application object properties...
I see a lot of answers have shifted to talk about using IDisposable for both managed and unmanaged resources. I'd suggest this article as one of the best explanations that I've found for how IDisposable should actually be used.
https://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About
For the actual question; should you use IDisposable to clean up managed objects that are taking up a lot of memory the short answer would be no. The reason is that once your object that is holding the memory goes out of scope it is ready for collection. At that point any referenced child objects are also out of scope and will get collected.
The only real exception to this would be if you have a lot of memory tied up in managed objects and you've blocked that thread waiting for some operation to complete. If those objects where not going to be needed after that call completed then setting those references to null might allow the garbage collector to collect them sooner. But that scenario would represent bad code that needed to be refactored - not a use case of IDisposable.
IDisposable is good for unsubscribing from events.
Your given code sample is not a good example for IDisposable usage. Dictionary clearing normally shouldn't go to the Dispose method. Dictionary items will be cleared and disposed when it goes out of scope. IDisposable implementation is required to free some memory/handlers that will not release/free even after they out of scope.
The following example shows a good example for IDisposable pattern with some code and comments.
public class DisposeExample
{
// A base class that implements IDisposable.
// By implementing IDisposable, you are announcing that
// instances of this type allocate scarce resources.
public class MyResource: IDisposable
{
// Pointer to an external unmanaged resource.
private IntPtr handle;
// Other managed resource this class uses.
private Component component = new Component();
// Track whether Dispose has been called.
private bool disposed = false;
// The class constructor.
public MyResource(IntPtr handle)
{
this.handle = handle;
}
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
component.Dispose();
}
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
CloseHandle(handle);
handle = IntPtr.Zero;
// Note disposing has been done.
disposed = true;
}
}
// Use interop to call the method necessary
// to clean up the unmanaged resource.
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~MyResource()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
}
public static void Main()
{
// Insert code here to create
// and use the MyResource object.
}
}
There are things that the Dispose() operation does in the example code that might have an effect that would not occur due to a normal GC of the MyCollection object.
If the objects referenced by _theList or _theDict are referred to by other objects, then that List<> or Dictionary<> object will not be subject to collection but will suddenly have no contents. If there were no Dispose() operation as in the example, those collections would still contain their contents.
Of course, if this were the situation I would call it a broken design - I'm just pointing out (pedantically, I suppose) that the Dispose() operation might not be completely redundant, depending on whether there are other uses of the List<> or Dictionary<> that are not shown in the fragment.
One problem with most discussions of "unmanaged resources" is that they don't really define the term, but seem to imply that it has something to do with unmanaged code. While it is true that many types of unmanaged resources do interface with unmanaged code, thinking of unmanaged resources in such terms isn't helpful.
Instead, one should recognize what all managed resources have in common: they all entail an object asking some outside 'thing' to do something on its behalf, to the detriment of some other 'things', and the other entity agreeing to do so until further notice. If the object were to be abandoned and vanish without a trace, nothing would ever tell that outside 'thing' that it no longer needed to alter its behavior on behalf of the object that no longer existed; consequently, the 'thing's usefulness would be permanently diminished.
An unmanaged resource, then, represents an agreement by some outside 'thing' to alter its behavior on behalf of an object, which would useless impair the usefulness of that outside 'thing' if the object were abandoned and ceased to exist. A managed resource is an object which is the beneficiary of such an agreement, but which has signed up to receive notification if it is abandoned, and which will use such notification to put its affairs in order before it is destroyed.
First of definition. For me unmanaged resource means some class, which implements IDisposable interface or something created with usage of calls to dll. GC doesn't know how to deal with such objects. If class has for example only value types, then I don't consider this class as class with unmanaged resources.
For my code I follow next practices:
If created by me class uses some unmanaged resources then it means that I should also implement IDisposable interface in order to clean memory.
Clean objects as soon as I finished usage of it.
In my dispose method I iterate over all IDisposable members of class and call Dispose.
In my Dispose method call GC.SuppressFinalize(this) in order to notify garbage collector that my object was already cleaned up. I do it because calling of GC is expensive operation.
As additional precaution I try to make possible calling of Dispose() multiple times.
Sometime I add private member _disposed and check in method calls did object was cleaned up. And if it was cleaned up then generate ObjectDisposedException
Following template demonstrates what I described in words as sample of code:
public class SomeClass : IDisposable
{
/// <summary>
/// As usually I don't care was object disposed or not
/// </summary>
public void SomeMethod()
{
if (_disposed)
throw new ObjectDisposedException("SomeClass instance been disposed");
}
public void Dispose()
{
Dispose(true);
}
private bool _disposed;
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)//we are in the first call
{
}
_disposed = true;
}
}
The most justifiable use case for disposal of managed resources, is preparation for the GC to reclaim resources that would otherwise never be collected.
A prime example is circular references.
Whilst it's best practice to use patterns that avoid circular references, if you do end up with (for example) a 'child' object that has a reference back to its 'parent', this can stop GC collection of the parent if you just abandon the reference and rely on GC - plus if you have implemented a finalizer, it'll never be called.
The only way round this is to manually break the circular references by setting the Parent references to null on the children.
Implementing IDisposable on parent and children is the best way to do this. When Dispose is called on the Parent, call Dispose on all Children, and in the child Dispose method, set the Parent references to null.
I think people are conflating the PATTERN of IDisposable with the primary purpose of IDisposable which was meant to help clean up unmanaged resources. We all know this. Some think the pattern has some sort of magical powers that clears memory and frees resources. The PATTERN does NOT do this. But the usage of the pattern with the methods that are implemented DO clear memory and free resources.
The pattern is simply a built in try{} finally{} block. Nothing more. Nothing less. So what does that mean? You can create a block of code that lets you do something at the end without having to do extra code for it. It provides a CUSTOM block you can use to segment code and scope.
My example:
//My way
using (var _ = new Metric("My Test"))
{
DoSomething(); //You now know all work in your block is being timed.
}
//MS mockup from memory
var sw = new Stopwatch();
sw.Start();
DoSomething(); //something fails? I never get the elapsed time this way
sw.Stop();
Metric class
public class Metric : IDisposable
{
private string _identifier;
private DateTime _start;
public Metric(string identifier)
{
_identifier = identifier;
_start = DateTime.Now;
}
public void Dispose()
{
Console.WriteLine(_identifier + " - " + (DateTime.Now - _start).TotalMilliseconds)
}
}

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.

Simply open and close dialog winform will increase memory usage

I am trying to reduce memory usage of a winForm application.
There is a main form and a setting form in the application. When "Setting" button been pressed, the setting form will popup as a modal form, the Setting form will load app.config data from config file and read them to memory as Hashtable. After the setting form closed, it will call Dispose method inherented from Windows.Forms.Form. The Dispose method is as simple as set the Hashtables and app.config object to null.
Show SettingForm as modalform:
private void btnSettings_Click(object sender, EventArgs e)
{
frmConfig form = new frmConfig();
form.StartPosition = FormStartPosition.CenterScreen;
//MessageBox.Show(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase));
form.ShowDialog(this);
form.Dispose();
}
Dispose method:
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
// Release managed resources
Logger.Verbose("Disposing SettingForm");
mySetting = null;
testFtp = null;
}
base.Dispose(disposing);
}
Note: mySetting is a instance of Class with all the app.config data been load into Hashtable, and testFtp is a custom object for ftp function. Should I implement Dispose method for this two class and using
mySetting.Dispose();
testFtp.Dispose();
instead of set them to null, as they are themself/deal with unmanaged resources?
But each time push the "Setting" button and close the setting form will increase private Byte for a few hundreds K. Memory leak? How could I get rid of it?
As you suggested near the end of your question, I would recommend implementing IDisposable on mySetting and testFtp. You should see better cleanup of resources once you have implemented the following:
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
// Release managed resources
Logger.Verbose("Disposing SettingForm");
mySetting.Dispose();
testFtp.Dispose();
}
base.Dispose(disposing);
}
Small edit:
Based on Nayan's answer and the answer he links to: I'd highly recommend the implementation of IDisposable. Using Forms and deriving from the Forms class screams, "Check for the need to implement IDisposable." This does not mean that your code should be implementing it, just that you should really check to make sure you don't need it. Forms typically have a lot of events published and subscribed to. Forms are also notorious for becoming a catch-all resource bucket, IMO.
The memory may not be getting released because of some other piece of code too. Since you have not provided much details, I'll assume right now that everything else is optimal.
The objects that you are working with are collected by garbage collector (as you know it). But they may not be released from memory when you want it. .NET objects are better left to garbage collector.
As per why the memory may not be getting released, you have the answers here.
Setting object reference to null doesn't make much difference. On the other hand, I've personally recorded some times, objects coming back alive (and pushed to old generations) because you're using them while setting null to same. It's another form of interference with GC, but your choice.
You may not need to implement IDisposable, but if you are working with streams, OS handles, unmanaged resources, you should then.
Edit:
The memory usage may be high, but it's GC's responsibility to free it as long as you do not keep references alive. So, if you have taken every precaution, it still may seem that your application is consuming lot of memory. That is acceptable as freeing the unreferenced objects is garbage collector's responsibility.
Why do you think it's a leak? GC is not obliged to free memory instantly, under some circumstances it may never actually perform the collection and that would be okay.
If you really need these kilobytes freed immediately, you might force GC to perform the clean-up just after the disposals, but it's a costly operation in general and may affect overall performance.

How to Dispose myClass with Garbage Collecter C#

I have a class and got a method that doin so many things in memory and need to be disposed when its jobs done.But i have looked for MSDN for solution.There is an example thats not solved my problem.When my Class is instanced and run this method my memory is getting bigger and bigger.How can i Dispose it when its job done ?
Here is my CODES ;
class Deneme
{
public Deneme()
{ }
~Deneme()
{
GC.Collect();
GC.SuppressFinalize(this);
}
public void TestMetodu()
{
System.Windows.Forms.MessageBox.Show("Test");
// This is my method that doing big jobs :)
}
}
Deneme CCCX = new Deneme();
CCCX.TestMetodu();
CCCX = null;
So i cant dispose it with this.
~Deneme()
{
GC.Collect();
GC.SuppressFinalize(this);
}
You don't need to use GC.Collect() or GC.SuppressFinalize(this);, because at this point, the garbage collector is already collecting the object.
You want to use the Dispose method, so you can encapsulate the object use in a using statement. Here is a link that will show you the pattern on how to implement it:
http://www.c-sharpcorner.com/UploadFile/Ashish1/dispose02152006095441AM/dispose.aspx
link to MSDN:
http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx
private bool IsDisposed
{
get;set;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~CLASS_NAME()
{
Dispose(false);
}
protected virtual void Dispose(bool disposedStatus)
{
if (!IsDisposed)
{
IsDisposed = true;
// Released unmanaged Resources
if (disposedStatus)
{
// Released managed Resources
}
}
}
implement IDisposable (with function Dispose) and then wrap the creation of your object in a using statement. (when the object goes out of scope (after the using block), the dispose will be called.)
Furthermore, never call GC.Collect().
Does your class directly use any unmanaged resources, or hold references to any IDisposable objects? If so, then you should probably implement IDisposable to clean-up those resources, and then wrap all uses of your class in a using block.
If your class only uses managed resources, and doesn't hold references to any IDisposable objects, then you should probably let the GC do its job without any interference. Just ensure that the lifetime of any instances of your class are kept as short as possible.
I think there are a few issues here and you need to look into this in a little more detail, the .net garbage collector usually does a pretty good job on its own and needs verly litle help from the developer.
Use the Dispose interface if you
really really need to (usually this
is to release any unmanaged
resources you may have used)
dont call gc.collect(), you can
really mess up the garbage
collection cycle
in you code use the using statement
on any objects that impliment
idisposable to ensure they are made
available for collection as soon as
possible.
To me it seems you need to look at the "big jobs" as it seems there may be a memory leak there, proper coding of that would probably alleviate the need to do any cleaning up afterwards.
here is a good read on GC
Well, I don't quite understand your example. If you hold unmanaged resources (like File handles etc.) you want to implement IDisposable and override the member it provides, Dispose.
There is a recommended pattern when using IDisposable which you can read about at the .NET docs for IDisposable.
However this is not a guarantee that your object will be collected when you call Dispose, only that the resources it uses is freed (as long as you've implemented your class correctly of course.) As the documentation states:
The primary use of this interface is
to release unmanaged resources. The
garbage collector automatically
releases the memory allocated to a
managed object when that object is no
longer used. However, it is not
possible to predict when garbage
collection will occur. Furthermore,
the garbage collector has no knowledge
of unmanaged resources such as window
handles, or open files and streams.
Use the Dispose method of this
interface to explicitly release
unmanaged resources in conjunction
with the garbage collector. The
consumer of an object can call this
method when the object is no longer
needed.
IDisposable is only there for freeing unmanaged resources, your class however is managed. It is under the control of the garbage collector.
What I think you are asking for is managing the lifetime of the managed object (your class), which is as far as I know not recommended unless there is a really really strong reason to. I don't exactly have the most exotic needs but I've never had to do this myself.
It's normal for an application to use more and more memory (up to a certain point) until the memory is needed for something else. There is no reason for the application to waste time with cleaning up unused objects if the memory isn't needed, the computer doesn't run any faster from having a lot of unused memory.
If the application continues to grow uncontrollably, then you have a problem. If the memory goes back down after a while, it's not a problem. You can test to minimise the program, that normally causes it to return as much memory to the system as possible.
If you are using objects in your method that implements IDisposable you should make sure that they are disposed properly. Otherwise they can't be cleaned up until the garbage collector has first called the Finalize method on each of them. There is a background thread that runs Finalize calls one at a time, so if you leave a lot of objects undisposed, it can take a while until they are all processed and ready to be cleaned up by garbage collection.

How to do C++ style destructors in C#?

I've got a C# class with a Dispose function via IDisposable. It's intended to be used inside a using block so the expensive resource it handles can be released right away.
The problem is that a bug occurred when an exception was thrown before Dispose was called, and the programmer neglected to use using or finally.
In C++, I never had to worry about this. The call to a class's destructor would be automatically inserted at the end of the object's scope. The only way to avoid that happening would be to use the new operator and hold the object behind a pointer, but that required extra work for the programmer isn't something they would do by accident, like forgetting to use using.
Is there any way to for a using block to be automatically used in C#?
Many thanks.
UPDATE:
I'd like to explain why I'm not accepting the finalizer answers. Those answers are technically correct in themselves, but they are not C++ style destructors.
Here's the bug I found, reduced to the essentials...
try
{
PleaseDisposeMe a = new PleaseDisposeMe();
throw new Exception();
a.Dispose();
}
catch (Exception ex)
{
Log(ex);
}
// This next call will throw a time-out exception unless the GC
// runs a.Dispose in time.
PleaseDisposeMe b = new PleaseDisposeMe();
Using FXCop is an excellent suggestion, but if that's my only answer, my question would have to become a plea to the C# people, or use C++. Twenty nested using statements anyone?
Where I work we use the following guidelines:
Each IDisposable class must have a finalizer
Whenever using an IDisposable object, it must be used inside a "using" block. The only exception is if the object is a member of another class, in which case the containing class must be IDisposable and must call the member's 'Dispose' method in its own implementation of 'Dispose'. This means 'Dispose' should never be called by the developer except for inside another 'Dispose' method, eliminating the bug described in the question.
The code in each Finalizer must begin with a warning/error log notifying us that the finalizer has been called. This way you have an extremely good chance of spotting such bugs as described above before releasing the code, plus it might be a hint for bugs occuring in your system.
To make our lives easier, we also have a SafeDispose method in our infrastructure, which calls the the Dispose method of its argument within a try-catch block (with error logging), just in case (although Dispose methods are not supposed to throw exceptions).
See also: Chris Lyon's suggestions regarding IDisposable
Edit:
#Quarrelsome: One thing you ought to do is call GC.SuppressFinalize inside 'Dispose', so that if the object was disposed, it wouldn't be "re-disposed".
It is also usually advisable to hold a flag indicating whether the object has already been disposed or not. The follwoing pattern is usually pretty good:
class MyDisposable: IDisposable {
public void Dispose() {
lock(this) {
if (disposed) {
return;
}
disposed = true;
}
GC.SuppressFinalize(this);
// Do actual disposing here ...
}
private bool disposed = false;
}
Of course, locking is not always necessary, but if you're not sure if your class would be used in a multi-threaded environment or not, it is advisable to keep it.
Unfortunately there isn't any way to do this directly in the code. If this is an issue in house, there are various code analysis solutions that could catch these sort of problems. Have you looked into FxCop? I think that this will catch these situations and in all cases where IDisposable objects might be left hanging. If it is a component that people are using outside of your organization and you can't require FxCop, then documentation is really your only recourse :).
Edit: In the case of finalizers, this doesn't really guarantee when the finalization will happen. So this may be a solution for you but it depends on the situation.
#Quarrelsome
If will get called when the object is moved out of scope and is tidied by the garbage collector.
This statement is misleading and how I read it incorrect: There is absolutely no guarantee when the finalizer will be called. You are absolutely correct that billpg should implement a finalizer; however it will not be called automaticly when the object goes out of scope like he wants. Evidence, the first bullet point under Finalize operations have the following limitations.
In fact Microsoft gave a grant to Chris Sells to create an implementation of .NET that used reference counting instead of garbage collection Link. As it turned out there was a considerable performance hit.
~ClassName()
{
}
EDIT (bold):
If will get called when the object is moved out of scope and is tidied by the garbage collector however this is not deterministic and is not guaranteed to happen at any particular time.
This is called a Finalizer. All objects with a finaliser get put on a special finalise queue by the garbage collector where the finalise method is invoked on them (so it's technically a performance hit to declare empty finalisers).
The "accepted" dispose pattern as per the Framework Guidelines is as follows with unmanaged resources:
public class DisposableFinalisableClass : IDisposable
{
~DisposableFinalisableClass()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// tidy managed resources
}
// tidy unmanaged resources
}
}
So the above means that if someone calls Dispose the unmanaged resources are tidied. However in the case of someone forgetting to call Dispose or an exception preventing Dispose from being called the unmanaged resources will still be tidied away, only slightly later on when the GC gets its grubby mitts on it (which includes the application closing down or unexpectedly ending).
The best practice is to use a finaliser in your class and always use using blocks.
There isn't really a direct equivalent though, finalisers look like C destructors, but behave differently.
You're supposed to nest using blocks, that's why the C# code layout defaults to putting them on the same line...
using (SqlConnection con = new SqlConnection("DB con str") )
using (SqlCommand com = new SqlCommand( con, "sql query") )
{
//now code is indented one level
//technically we're nested twice
}
When you're not using using you can just do what it does under the hood anyway:
PleaseDisposeMe a;
try
{
a = new PleaseDisposeMe();
throw new Exception();
}
catch (Exception ex) { Log(ex); }
finally {
//this always executes, even with the exception
a.Dispose();
}
With managed code C# is very very good at looking after its own memory, even when stuff is poorly disposed. If you're dealing with unmanaged resources a lot it's not so strong.
This is no different from a programmer forgetting to use delete in C++, except that at least here the garbage collector will still eventually catch up with it.
And you never need to use IDisposable if the only resource you're worried about is memory. The framework will handle that on it's own. IDisposable is only for unmanaged resources like database connections, filestreams, sockets, and the like.
A better design is to make this class release the expensive resource on its own, before its disposed.
For example, If its a database connection, only connect when needed and release immediately, long before the actual class gets disposed.

Categories

Resources