Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C# and the NET Platform, Second Edition - Andrew Troelsen.pdf
Скачиваний:
67
Добавлен:
24.05.2014
Размер:
22.43 Mб
Скачать

Finalizing a Type

 

C# and the .NET Platform, Second Edition

 

by Andrew Troelsen

ISBN:1590590554

As you might have gathered from the previous discussion, the .NET garbage collection scheme is rather

Apress © 2003 (1200 pages)

nondeterministic in nature. In other words, you are typically unable to determine exactly when an object

This comprehensive text starts with a brief overview of the

will be deallocatedC#fromlanguagememoryand.thenAlthoughquicklythismovesapproachto keytotechnicalmemoryandmanagement can simplify your coding efforts at somearchitecturallevels,issuesyou areforleft.NETwithdevelopersthe unappealing. byproduct of your objects possibly holding

ontounmanagedresources (raw HWNDs, raw Win32 file handles, etc.) longer than necessary. When you build .NET types that interact with unmanaged resources (a common task when working with platform

Table of Contents

invocation and COM interoperability), you will most likely wish to ensure that this resource is released in a

C# and the .NET Platform, Second Editwhimon

timely manner rather than at the of the .NET garbage collector.

Introduction

To account for such situations, one choice you have as a C# class designer is to override the virtual

Part One - Introducing C# and the .NET Platform

System.Object.Finalize() method (the default implementation does nothing). Believe it or not, most of the

Chapter 1 - The Philosophy of .NET

time you will not need to support a custom implementation of the Finalize() method. In fact, the only

Chapter 2 - Building C# Applications

reason you will be required to do so is if your custom C# classes make use of unmanaged resources that

Part Two - The C# Programming Language

are typically obtained by directly calling into the Win32 API. On the other hand, if your C# types do not

Chapter 3 - C# Language Fundamentals

make use of unmanaged resources but only make use of managed types, you are not required to

Chapter 4 - Object-Oriented Programming with C#

implement a custom Finalize() method at all.

Chapter 5

- Exceptions and Object Lifetime

Chapter 6

- Interfaces and Collections

Nevertheless, assume you have a type that has acquired various unmanaged resources and wish to

Cha ter 7

- Callback Interfaces, D legates, and Events

support a custom version of System.Object.Finalize() to ensure proper cleanup of the internal unmanaged

Chapter 8

- Advanced C# Type Co struction Techniques

resources. While this is all well and good, the odd thing is that the C# language does not allow you to

PartdirectlyThreeoverride- P ogrammithe Finalize()g with .methodNET Assembliesusing standard C# syntax:

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

public class FinalizedCar

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

{

Part Four - Leveraging the .NET Libraries

// Compile time error!

Chapter 12 - Object Serialization and the .NET Remoting Layer protected override void Finalize(){ }

Chapter} 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Rather, when you wish to configure your custom C# class types to override the Finalize() method, you

Chapter 16 - The System.IO Namespace

make use of the following (C++-like) destructor syntax to achieve the same effect:

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

// This Car overrides System.Object.Finalize().

Chapter 18 - ASP.NET Web Pages and Web Controls

class FinalizedCar

Chapter 19 - ASP.NET Web Applications

{

Chapter 20 - XML Web Services

Index ~FinalizedCar()

{Console.WriteLine("=> Finalizing car..."); }

List of Figures

}

List of Tables

The C# destructor-style syntax can be understood as a shorthand notation for the following code:

protected override void Finalize()

{

try

{Console.WriteLine("=> Finalizing car..."); } finally

{base.Finalize(); }

}

In fact, if you were to check out the CIL that is generated for classes supporting the C# destructor method (via ildasm.exe), you will find that an override is indeed made for the virtual System.Object.Finalize() method. Also notice that the CIL code will automatically call the base class Finalize() method on your

behalf:

 

C# and the .NET Platform, Second Edition

 

 

by Andrew Troelsen

ISBN:1590590554

.method family hidebysig virtual instance void

 

Apress © 2003 (1200 pages)

 

 

Finalize() cil managed

 

{

This comprehensive text starts with a brief overview of the

C# language and then quickly moves to key technical and

// Code sizearchitectural20issues(0x14)for .NET developers.

 

.maxstack 1

 

 

.try

 

 

 

Table{of Contents

 

 

C# andILthe_0000:.NET Platform,ldstrSecond Edition"=> Finalizing car..."

IntroductionIL_0005: call

void [mscorlib]System.Console::WriteLine(string)

Part OneIL-_Introducing000a: leave.sC# and the .NETIL_0013Platform

 

Chapter} //1

-endThe Philosophy.try

of .NET

 

.finally

Chapter 2 - Building C# Applications

Part{Two - The C# Programming Language

IL_000c: ldarg.0

Chapter 3 - C# Language Fundamentals

IL_000d: call instance void [mscorlib]System.Object::Finalize()

Chapter 4 - Object-Oriented Programming with C#

IL_0012: endfinally

Chapter 5 - Exceptions and Object Lifetime

}// end handler

Chapter 6 - Interfaces and Collections

IL_0013: ret

Chapter 7 - Callback Interfaces, Delegates, and Events

}

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

(Indirectly) Invoking System.Object.Finalize()

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

As mentioned, the .NET runtime will trigger a garbage collection when it requires more memory than is

Part Four - Leveraging the .NET Libraries

currently available on the managed heap. Therefore, if you have created an application that is intended to

Chapter 12 - Object Serialization and the .NET Remoting Layer

run for lengthy periods of time (such as a background service), garbage collections may occur few and far

Chapter 13 - Building a Better Window (Introducing Windows Forms) between over the course of the application's lifetime.

Chapter 14 - A Better Painting Framework (GDI+)

ChapterIt is important15 - Programmingto note thatwithfinalizationWindowswillFormsautomaticallyContro s take place when an application domain is unloaded

by the CLR. Application domains (or simply AppDomains) will be examined in greater detail later in this

Chapter 16 - The System.IO Namespace

text. For the time being, simply assume that an AppDomain is the application itself. Thus, you can rest

Chapter 17 - Data Access with ADO.NET

assured that a finalizable object will have its cleanup logic triggered upon application shutdown. This

Part Five - Web Applications and XML Web Services

brings us to the next rule of garbage collection.

Chapter 18 - ASP.NET Web Pages and Web Controls Chapter 19 - ASP.NET Web Applications

ChapterRule:20 -WhenXML Weban AppDomainServices is unloaded, the Finalize() method is invoked for all finalizable objects.

Index

To illustrate, ponder the following illustrative example:

List of Figures

List of Tables

namespace SimpleFinalize

{

class FinalizedCar

{

~FinalizedCar()

{ Console.WriteLine("=> Finalizing car..."); }

}

class FinalizeApp

{

static void Main(string[] args)

{

Console.WriteLine("***** Making object *****");

FinalizedCar fc = new FinalizedCar();

Console.WriteLine("***** Exiting main *****");

}

}

}

C# and the .NET Platform, Second Edition

by Andrew Troelsen

 

ISBN:1590590554

 

 

 

Apress © 2003 (1200 pages)

 

 

The output of thisThisprogramcomprehensivecan be seent xtinstartsFigurewith5-a12brief. Noticeov rviewthat theof thefinalization message is

 

 

 

 

 

 

C# language and then quickly m

ves to key technical and

automatically printed to the console once the program exits. Of course, a proper finalizer would free up

architectural issues for .NET developers.

some set of unmanaged resources, but I think the point has been made.

Table

C# and

Part

Chapter

Chapter

Part Two - The C# Programming Language

Figure 5-12: Finalizers are called automatically upon application shutdown.

Chapter 3 - C# Language Fundamentals

Chapter 4 - Object-Oriented Programming with C#

Chapter 5 - Exceptions and Object Lifetime

Chapter 6 - Interfaces and Collections

Chapter 7 - Callback Interfaces, Delegates, and Events

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

The FinalizationC# and theProcess.NET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

Given that finalization is guaranteed to take place when your application exits, you may be tempted to

Apress © 2003 (1200 pages)

support C#-style destructors on all of your types. But don't. First of all, always remember that the role of a

This comprehensive text starts with a brief overview of the

finalizer is to ensureC# languagethat a .NETandobjectth n quicklycan cleanmovesup tounmanagedkey technicalresourcesand . Thus, if you are building a type that does notarchitectmake useralofissunmanagedes for .NET developersentities, finalization. is of little use. However, there is a more practical reason to avoid supporting a finalize method: Finalization takes time.

TableWhenofyouContentsplace an object onto the managed heap using the new operator, the runtime automatically C#determinesand the .NETif yourPlatform,objectSecondsupportsEditiona custom Finalize() method. If so, the object is marked as finalizable,

and a pointer to this object is stored on an internal queue named (of course) the finalization queue. Simply

Introduction

put, the finalization queue is a table maintained by the CLR that points to each and every object that must

Part One - Introducing C# and the .NET Platform

be finalized before it is removed from the heap.

Chapter 1 - The Philosophy of .NET

Chapter 2 - Building C# Applications

When the garbage collector determines it is time to free an object from memory, it examines each entry

Part Two - The C# Programming Language

cataloged on the finalization queue, and copies the object off the heap to yet another CLR-managed

Chapter 3 - C# Language Fundamentals

structure termed the finalization reachable table (often abbreviated as freachable, and pronounced "F-

Chapter 4 - Object-Oriented Programming with C#

reachable"). At this point, a separate thread is spawned to invoke the Finalize() method for each object on

Chapter 5 - Exceptions and Object Lifetime

the freachable table at the next garbage collection.

Chapter 6 - Interfaces and Collections

ChapterThe bottom7 - Callbackline is thatInterfaces,when youDelegates,build customand Eventstype that overrides the System.Object.Finalize() method,

the .NET runtime will ensure that this member is called once your object is removed from the managed

Chapter 8 - Advanced C# Type Construction Techniques

heap. However, this comes at a cost in terms of application performance.

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

SOURCE The SimpleFinalize project is included under the Chapter 5 subdirectory.

Chapter 10 - Processes, AppDomains, Contexts, and Threads

CODE

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

Building anC#AdandHocthe .NETDestructionPlatform, SecondMethodEditi n

by Andrew Troelsen

ISBN:1590590554

As you have seen, the process of finalizing an object is quite time consuming. Ideally, you should design

Apress © 2003 (1200 pages)

your objects in such a way so they do not need to be marked as finalizable in the first place. However,

This comprehensive text starts with a brief overview of the

when a type manipulatesC# l nguageunmanagedand thenresources,quickly movesyoutodokeyneedtechnicalto ensureand they are released in a timely and predictable mannerarchitectural. While youissuescouldforsupport.NET developersa C# destructor. (and incur the overhead of being finalized), there are better ways.

TableOneofalternativeCo tentsis to define a custom ad hoc method that you can assume all objects in your system C#implementand the ..NETLet'sPlatform,call thisSecondmethodEditionDispose(). The assumption is that when the object user is finished using

your type, it manually calls Dispose() before allowing the object reference to drop out of scope. In this way,

Introduction

your objects can perform any amount of cleanup necessary of unmanaged resources without incurring the

Part One - Introducing C# and the .NET Platform

hit of being placed on the finalization queue and without waiting for the garbage collector to trigger the

Chapter 1 - The Philosophy of .NET

class' finalization logic:

Chapter 2 - Building C# Applications

Part Two - The C# Programming Language

Chapter// Equipping3 - C# Languageour classFundamenwithalsan ad hoc destruction method.

public Car

Chapter 4 - Object-Oriented Programming with C#

{

Chapter 5 - Exceptions and Object Lifetime

...

Chapter 6 - Interfaces and Collections

// This is a custom method we expect the object user to call manually.

Chapter 7 - Callback Interfaces, Delegates, and Events

public void Dispose()

Chapter 8 - Advanced C# Type Construction Techniques

{/* Clean up your internal unmanaged resources. */}

Part Three - Programming with .NET Assemblies

}

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Of course, the name of this method is completely up to you. While Dispose() is a very common name, if

Part Four - Leveraging the .NET Libraries

you are building a class that manipulates a physical file, you may opt to call this member Close().

Chapter 12 - Object Serialization and the .NET Remoting Layer

However, any name will do (ShutDown(), Kill(), DestroyMeNow(), and so forth).

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Note To ensure that unmanaged resources are always cleaned up appropriately, the implementation

Chapter 14 - A Better Painting Framework (GDI+)

of a Dispose() method should be safely callable multiple times without throwing an exception.

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

ChaptTherIDisposable17 - Data Access withInterfaceADO.NET

Part Five - Web Applications and XML Web Services

In order to provide symmetry among all objects that support an explicit destruction routine, the .NET class

Chapter 18 - ASP.NET Web Pages and Web Controls

libraries define an interface named IDisposable that (surprise, surprise) supports a single member named

Chapter 19 - ASP.NET Web Applications

Dispose():

Chapter 20 - XML Web Services

Index

public interface IDisposable

List of Figures

{

List of Tables

public void Dispose();

}

Now, rest assured that the concepts behind interface-based programming are fully detailed in Chapter 6. Until then, understand that the recommended design pattern to follow is to implement the IDisposable interface for all types that wish to support an explicit form of resource deallocation. Thus, you may update the Car type as follows:

// Implementing IDisposable.

public Car : IDisposable

{

...

// This is still a custom method we expect the object user to call

// manually.

 

C# and the .NET Platform, Second Edition

 

public void Dispose()

ISBN:1590590554

{

by Andrew Troelsen

Apress © 2003 (1200 pages)

 

}

// Clean up your internal unmanaged resources.

This comprehensive text starts with a brief overview of the

C# language and then quickly moves to key technical and

}

architectural issues for .NET developers.

 

Again, using this approach, you provide the object user with a way to manually dispose of acquired

Table of Contents

resources as soon as possible, and avoid the overhead of being placed on the finalization queue. The

C# and the .NET Platform, Second Edition calling logic is straightforward:

Introduction

Part One - Introducing C# and the .NET Platform

namespace DisposeMe

Chapter 1 - The Philosophy of .NET

{

Chapter 2 - Building C# Applications

public class App

Part Two - The C# Programming Language

{

Chapter 3 - C# Language Fundamentals

public static int Main(string[] args)

Chapter 4 - Object-Oriented Programming with C#

{

Chapter 5 - Exceptions and Object Lifetime

Car c1 = new Car("Car one", 40, 10);

Chapter 6 - Interfaces and Collections

c1.Dispose();

Chapter 7 - Callback Interfaces, Delegates, and Events

return 0;

Chapter 8 - Advanced} // C1C#isTypestillConstructiontheT chniquesheap and may be collected at this point.

Part Three} - Programming with .NET Assemblies

Chapter} 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

This example exposes yet another rule of working with garbage collected types.

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

ChapterRule:13 -AlwaysBuildingcallBetterDispose()Windforwany(IntroduobjectingyouWindowsmanuallyForms)allocate to the heap. The assumption you

Chaptershould14 - makeA Betteris thatPaintingif theFrameworkclass designer(GDI+)chose to support the Dispose() method (or a named Chapteralternative15 - Programmingsuch as Close()),with Windowsthe typeFormshas Csomentrolscleanup to perform.

Chapter 16 - The System.IO Namespace

As you may be guessing, it is possible for a single class to support a C#-style destructor as well as

Chapter 17 - Data Access with ADO.NET

implement the IDisposable interface. You see this technique in just a moment.

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Reusing the C# "using" Keyword

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

When you are handling a managed object that implements IDisposable, it will be quite common to make

Index

use of structured exception handling to ensure the type's Dispose() method is called in the event of a

List of Figures runtime exception:

List of Tables

public void SomeMethod()

{

Car c = new Car(); try

{// Use the car. } catch

{ // Catch any exceptions here. } finally

{

// Always call Dispose(), error or not. c.Dispose();

}

}

While this is a fine example of defensive programming, the truth of the matter is that few developers are

C# and the .NET Platform, Second Edition

thrilled by the prospects of wrapping each and every type within a try/catch/finally block just to ensure the

by Andrew Troelsen ISBN:1590590554

type's Dispose() method is called. To achieve the same result in a much less obtrusive manner, C#

Apress © 2003 (1200 pages)

supports a special bit of syntax that looks like this:

This comprehensive text starts with a brief overview of the

C# language and then quickly moves to key technical and

public void SomeMethod()

architectural issues for .NET developers.

{

using(Car c = new Car())

Table of{Contents

C# and the .NET//

UsePlatform,theSecondcar. Edition

Introduction //

Dispose() is called automatically when the

Part One - Introducing// usingC#blockand theexits..NET Platform

Chapter}1

- The Philosophy of .NET

Chapter}

2

- Building C# Applications

Part Two - The C# Programming Language

Chapter

3

- C# Language Fundamentals

Unfortunately, the "using" keyword now has a double meaning (specifying namespaces and triggering a

Chapter

4

- Object-Oriented Programming with C#

Dispose() method). Nevertheless, when you are working with .NET types that support the IDisposable

Chapter

5

- Exceptions and Object Lifetime

interface, this syntactical construct will ensure that the object "being used" will automatically have its

Chapter

6

- Interfaces and Collections

Dispose() method called once the using block has exited. On the other hand, if you specify a type that

Chapter

7

- Callback Interfaces, Delegates, and Events

does not implement IDisposable within the using declaration, you are issued a compile time error.

Chapter

8

- Advanced C# Type Construction Techniques

Part ThreeSOURCE- ProgrammingThewithDisposableCar.NET Assembliesproject is included under the Chapter 5 subdirectory.

ChapterCODE9 - Understanding .NET Assemblies

Chapter

10

- Processes, AppDomains, Contexts, and Threads

Chapter

11

- Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

Соседние файлы в предмете Программирование