Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

When and How to Use Dispose and Finalize in C# : Page 4

Although the .NET framework frees managed memory and resources transparently, it's not as adept at freeing unmanaged resources; you have to help it out by implementing the Dispose and Finalize patterns in your code.


advertisement
Suppressing Finalization
After the Dispose method has been called on an object, you should suppress calls to the Finalize method by invoking the GC.SuppressFinalize method as a measure of performance optimization. Note that you should never change the order of calls in the finalization context (first Dispose(true) and then GC.SupressFinalize) to ensure that the latter gets called if and only if the Dispose method has completed its operation successfully.

The following code illustrates how to implement both the Dispose and Finalize pattern for a class.

public class Base: IDisposable { private bool isDisposed = false; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if(!isDisposed) { if (disposing) { // Code to dispose the managed resources // held by the class } } // Code to dispose the unmanaged resources // held by the class isDisposed = true; base.Dispose(disposing); } ~Base() { Dispose (false); } }

You should not reimplement IDisposable for a class that inherits from a base class in which IDispose has already been implemented. The following code snippet may help you understand this concept:

public class Base: IDisposable { private bool isDisposed = false; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if(!isDisposed) { if (disposing) { // Code to dispose managed resources // held by the class } } // Code to dispose unmanaged resources // held by the class isDisposed = true; base.Dispose(disposing); } ~Base() { Dispose (false); } } public class Derived: Base { protected override void Dispose(bool disposing) { if (disposing) { // Code to cleanup managed resources held by the class. } // Code to cleanup unmanaged resources held by the class. base.Dispose(disposing); } // Note that the derived class does not // re-implement IDisposable }

In the preceding code, what if the Dispose method were to throw an exception? In that case, the Finalize method would exit prematurely, and the memory would never be reclaimed. Hence, in such situations, it is advisable to wrap the Dispose method in a try-catch block. This will prevent finalization exceptions from orphaning the object.

Note the following points when implementing disposable types:

  • Implement IDisposable on every type that has a finalizer
  • Ensure that an object is made unusable after making a call to the Dispose method. In other words, avoid using an object after the Dispose method has been called on it.
  • Call Dispose on all IDisposable types once you are done with them
  • Allow Dispose to be called multiple times without raising errors.
  • Suppress later calls to the finalizer from within the Dispose method using the GC.SuppressFinalize method
  • Avoid creating disposable value types
  • Avoid throwing exceptions from within Dispose methods
In a managed environment, the GC takes care of freeing unused objects. In contrast, in unmanaged languages such as C, developers had to release unused objects explicitly that were created dynamically in the heap. However, a proper understanding of both the Dispose and Finalize methods goes a long way toward designing efficient applications.



Joydip Kanjilal has over 10 years of industry experience with C, C++, Java, C#, VB, VC++, ASP.Net, XML, Design Patterns, UML, etc. He currently works as a senior project leader in a reputable multinational company in Hyderabad, India, and has contributed articles on .NET and related technologies to www.aspalliance.com.
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap