15.02.2015 Views

C# 4 and .NET 4

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

314 ❘ ChaPTer 13 memOry mAnAGement And pOinters<br />

As shown, the code implemented in the ~MyClass destructor is wrapped in a try block contained in the<br />

Finalize() method. A call to the parent’s Finalize() method is ensured by placing the call in a finally<br />

block. We discuss try <strong>and</strong> finally blocks in Chapter 15, “Errors <strong>and</strong> Exceptions.”<br />

Experienced C++ developers make extensive use of destructors, sometimes not only to clean up resources<br />

but also to provide debugging information or perform other tasks. <strong>C#</strong> destructors are used far less than<br />

their C++ equivalents. The problem with <strong>C#</strong> destructors as compared to their C++ counterparts is that<br />

they are nondeterministic. When a C++ object is destroyed, its destructor runs immediately. However,<br />

because of the way the garbage collector works when using <strong>C#</strong>, there is no way to know when an object’s<br />

destructor will actually execute. Hence, you cannot place any code in the destructor that relies on being run<br />

at a certain time, <strong>and</strong> you should not rely on the destructor being called for different class instances in any<br />

particular order. When your object is holding scarce <strong>and</strong> critical resources that need to be freed as soon as<br />

possible, you do not want to wait for garbage collection.<br />

Another problem with <strong>C#</strong> destructors is that the implementation of a destructor delays the final removal of<br />

an object from memory. Objects that do not have a destructor are removed from memory in one pass of the<br />

garbage collector, but objects that have destructors require two passes to be destroyed: The first pass calls<br />

the destructor without removing the object, <strong>and</strong> the second pass actually deletes the object. In addition, the<br />

runtime uses a single thread to execute the Finalize() methods of all objects. If you use destructors<br />

frequently, <strong>and</strong> use them to execute lengthy cleanup tasks, the impact on performance can be noticeable.<br />

The idisposable interface<br />

In <strong>C#</strong>, the recommended alternative to using a destructor is using the System.IDisposable interface.<br />

The IDisposable interface defines a pattern (with language-level support) that provides a deterministic<br />

mechanism for freeing unmanaged resources <strong>and</strong> avoids the garbage collector–related problems inherent<br />

with destructors. The IDisposable interface declares a single method named Dispose(), which takes no<br />

parameters <strong>and</strong> returns void. Here is an implementation for MyClass:<br />

class MyClass: IDisposable<br />

{<br />

public void Dispose()<br />

{<br />

// implementation<br />

}<br />

}<br />

The implementation of Dispose() should explicitly free all unmanaged resources used directly by an object<br />

<strong>and</strong> call Dispose() on any encapsulated objects that also implement the IDisposable interface. In this<br />

way, the Dispose() method provides precise control over when unmanaged resources are freed.<br />

Suppose that you have a class named ResourceGobbler, which relies on the use of some external resource<br />

<strong>and</strong> implements IDisposable. If you want to instantiate an instance of this class, use it, <strong>and</strong> then dispose of<br />

it, you could do it like this:<br />

ResourceGobbler theInstance = new ResourceGobbler();<br />

// do your processing<br />

theInstance.Dispose();<br />

Unfortunately, this code fails to free the resources consumed by theInstance if an exception occurs<br />

during processing, so you should write the code as follows using a try block (which is discussed fully in<br />

Chapter 15):<br />

ResourceGobbler theInstance = null;<br />

try<br />

{<br />

theInstance = new ResourceGobbler();<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!