clr exception handing and memory management

40
Effective .NET Framework based Effective .NET Framework based Development: Development: Exception Exception Handing and Memory Handing and Memory Management Management Brad Abrams Brad Abrams Lead Program Manager Lead Program Manager Common Language Runtime Team Common Language Runtime Team Microsoft Corporation Microsoft Corporation [email protected] http://blogs.msdn.com/brada

Upload: shiny-zhu

Post on 19-Jun-2015

2.782 views

Category:

Technology


0 download

DESCRIPTION

clr exception handling and memory manage.

TRANSCRIPT

Page 1: CLR Exception Handing And Memory Management

Effective .NET Framework based Effective .NET Framework based

Development:Development: Exception Exception Handing and Memory Handing and Memory

ManagementManagement

Brad AbramsBrad AbramsLead Program ManagerLead Program ManagerCommon Language Runtime TeamCommon Language Runtime TeamMicrosoft Corporation Microsoft Corporation

[email protected] http://blogs.msdn.com/brada

Page 2: CLR Exception Handing And Memory Management

AgendaAgenda

Exception Exception ““Cleaner, more elegant, and wrong.” Cleaner, more elegant, and wrong.”

Raymond Chen Raymond Chen ((http://blogs.msdn.com/oldnewthing/)http://blogs.msdn.com/oldnewthing/)

Memory ManagementMemory Management“I'm addicted to deterministic destruction“I'm addicted to deterministic destruction” ”

Chris Sells Chris Sells ((http://www.sellsbrothers.com/)http://www.sellsbrothers.com/)

Page 3: CLR Exception Handing And Memory Management

Exception Handling Exception Handling QuestionsQuestions

Throwing an exceptionThrowing an exception What exception to throw?What exception to throw? What data to include in the exception?What data to include in the exception?

Managing resourcesManaging resources What resources need to be cleaned up?What resources need to be cleaned up? When should they be cleaned up?When should they be cleaned up?

Catching an ExceptionCatching an Exception When to catch an exception?When to catch an exception? How to report the error?How to report the error? What to do with the control follow: terminate What to do with the control follow: terminate

the app, abort the transaction, ignore the the app, abort the transaction, ignore the exception, disable some functionality, etc.?exception, disable some functionality, etc.?

Page 4: CLR Exception Handing And Memory Management

When to Throw?When to Throw?

Exceptions rather than error codesExceptions rather than error codes Robust: failures get noticedRobust: failures get noticed

Your method is defined to do Your method is defined to do something…something… If it succeeds in performing its purpose, If it succeeds in performing its purpose,

returnreturn If it fails to do what it was written to do, If it fails to do what it was written to do,

throw an exceptionthrow an exception

Page 5: CLR Exception Handing And Memory Management

What to throw?What to throw?

Use or subclass existing exceptions Use or subclass existing exceptions if at all possibleif at all possible

Only create separate classes if you Only create separate classes if you think developers will handle the think developers will handle the exception differentlyexception differently

try { //some operation}catch (FileNotFoundException fe) { //do some set of work}catch (DriveNotFoundException be) { //do some other set of work}

try { //some operation}catch (FileNotFoundException fe) { //do some set of work}catch (DriveNotFoundException be) { //do some other set of work}

Page 6: CLR Exception Handing And Memory Management

Throwing an ExceptionThrowing an Exception

Do not just map error codes on to a Do not just map error codes on to a single exception with an error code single exception with an error code property (property (e.g.e.g., the WMIException), the WMIException) Use separate exception typesUse separate exception types

Error MessagesError Messages Consider localization Consider localization Use a complete sentence (end in a Use a complete sentence (end in a

period)period) Don’t expose privacy related Don’t expose privacy related

information (such as file paths)information (such as file paths)

Page 7: CLR Exception Handing And Memory Management

PerformancePerformance Minimize the number of exceptions Minimize the number of exceptions

you throw in your API’s success code-you throw in your API’s success code-pathspaths You don’t pay for exceptions until you You don’t pay for exceptions until you

throw in managed codethrow in managed code Throwing exceptions degrades Throwing exceptions degrades

performanceperformance Perf counters tell you exactly how many Perf counters tell you exactly how many

exceptions your application is throwingexceptions your application is throwing Only an issue when using exceptions as Only an issue when using exceptions as

control flowcontrol flow Consider providing a way to avoid an Consider providing a way to avoid an

exception being thrownexception being thrown

Page 8: CLR Exception Handing And Memory Management

Performance (continued)Performance (continued)

int i;try { i = Int32.Parse(“123”);} catch (FormatException ) { Console.WriteLine (“Invalid”);}

int i;try { i = Int32.Parse(“123”);} catch (FormatException ) { Console.WriteLine (“Invalid”);}

int i;if (!Int32.TryParse (“123”, out i)) { Console.Writeline(“Invalid”);}

int i;if (!Int32.TryParse (“123”, out i)) { Console.Writeline(“Invalid”);}

Page 9: CLR Exception Handing And Memory Management

Managing ResourcesManaging Resources

You should use try..finally 10 times You should use try..finally 10 times as often as try..catchas often as try..catch Catches eat exceptions making it hard Catches eat exceptions making it hard

to debugto debug Finally allows you to clean up, but let Finally allows you to clean up, but let

the exception continuethe exception continue

Page 10: CLR Exception Handing And Memory Management

Managing ResourcesManaging Resources

You may catch exceptions to re-throw them with a You may catch exceptions to re-throw them with a clearer nameclearer name Typical at an “API” boundaryTypical at an “API” boundary

Always nest the underlying exceptionAlways nest the underlying exception Catch-and-rethrow has many of the benefits as Catch-and-rethrow has many of the benefits as

try..finallytry..finally But, be aware of debugging issues with catch..throw new() But, be aware of debugging issues with catch..throw new()

and catch..throw;and catch..throw; Generally, cleanup code should go in finalizerGenerally, cleanup code should go in finalizer

try {. . .}catch (DivisionByZeroException e) { // do clean up work throw new BetterException (message, e);}

try {. . .}catch (DivisionByZeroException e) { // do clean up work throw new BetterException (message, e);}

Page 11: CLR Exception Handing And Memory Management

Catching ExceptionsCatching Exceptions

Do not catch and eat exceptionsDo not catch and eat exceptions Exceptions should be handled only where Exceptions should be handled only where

there is enough context to do the right thingthere is enough context to do the right thing That generally means exceptions should be That generally means exceptions should be

caught as high in the application as possiblecaught as high in the application as possible Mistake – catch the exception, report the Mistake – catch the exception, report the

error and rethrow it. error and rethrow it. Only catch where you can handle itOnly catch where you can handle it

Mistake – catch the exception, turn it into Mistake – catch the exception, turn it into a bool pass/fail and return the bool  a bool pass/fail and return the bool 

Page 12: CLR Exception Handing And Memory Management

Catching ExceptionsCatching Exceptions Consider including a try/catch at the top Consider including a try/catch at the top

of a thread’s stack if the error can be of a thread’s stack if the error can be handled properlyhandled properly Unhandled exceptions at the top of the main Unhandled exceptions at the top of the main

thread will terminate the appthread will terminate the app In 2.0, unhandled exceptions at the top of the In 2.0, unhandled exceptions at the top of the

stack on any thread will terminate the appstack on any thread will terminate the app But avoid catch blocks in finalizersBut avoid catch blocks in finalizers

Be aware: In many cases it is “appropriate” to Be aware: In many cases it is “appropriate” to let the app terminate let the app terminate

Be aware of (but ignore) exceptions that Be aware of (but ignore) exceptions that don’t inherit from System.Exceptiondon’t inherit from System.Exception Allowed in V1.0\V1.1, likely addressed in V2.0Allowed in V1.0\V1.1, likely addressed in V2.0

Brad Abrams
add something about See UnhandledException event off AppDomain in
Page 13: CLR Exception Handing And Memory Management

catch (Exception e) is catch (Exception e) is your friendyour friend

Myth: Catching Exception is evilMyth: Catching Exception is evil This is motivated by a desire to avoid catching This is motivated by a desire to avoid catching

low level exceptions such as low level exceptions such as OutOfMemoryException, and OutOfMemoryException, and StackOverflowExceptionStackOverflowException

Do catch every exception you should handle Do catch every exception you should handle Don’t attempt to catch every exception a Don’t attempt to catch every exception a

method could throwmethod could throw Its ugly, version brittle, and difficult to testIts ugly, version brittle, and difficult to test

Catch what you need to handle, let the rest Catch what you need to handle, let the rest passpass

Page 14: CLR Exception Handing And Memory Management

AgendaAgenda

Exception Exception ““Cleaner, more elegant, and wrong.” Cleaner, more elegant, and wrong.”

Raymond Chen Raymond Chen ((http://blogs.msdn.com/oldnewthing/)http://blogs.msdn.com/oldnewthing/)

Memory ManagementMemory Management““I'm addicted to deterministic I'm addicted to deterministic

destruction” destruction” Chris Sells Chris Sells ((http://www.sellsbrothers.com/)http://www.sellsbrothers.com/)

Page 15: CLR Exception Handing And Memory Management

Memory ManagementMemory Management

The GC does an excellent job managing The GC does an excellent job managing “managed” memory“managed” memory

GC doesn’t manage external resources GC doesn’t manage external resources (DB connections, HWnds, (DB connections, HWnds, etc.etc.))

Generational Mark-and-sweep garbage Generational Mark-and-sweep garbage collection means non-deterministic collection means non-deterministic finalizationfinalization Exact time of finalization is unspecifiedExact time of finalization is unspecified Order of finalization is unspecifiedOrder of finalization is unspecified Thread is unspecifiedThread is unspecified

Page 16: CLR Exception Handing And Memory Management

Resource Management Resource Management

If you are encapsulating external If you are encapsulating external resources:resources: Add a finalizer (C# destructor) to guarantee Add a finalizer (C# destructor) to guarantee

the resource will eventually be freedthe resource will eventually be freed Provide developers an explicit way to free Provide developers an explicit way to free

external resourcesexternal resources Formalized in the IDisposable interfaceFormalized in the IDisposable interface

Signals to users they need to explicitly Dispose of Signals to users they need to explicitly Dispose of instancesinstances

Enables C# and VB (2005) Enables C# and VB (2005) usingusing support support

Page 17: CLR Exception Handing And Memory Management

FinalizersFinalizers Object.Finalize() is not accessible Object.Finalize() is not accessible

in C#in C# VERY different than C++’s VERY different than C++’s

destructorsdestructorspublic class Resource{ ~Resource() { ... }}

public class Resource{ ~Resource() { ... }}

public class Resource{ protected override void Finalize() { try { ... } finally { base.Finalize(); } }}

public class Resource{ protected override void Finalize() { try { ... } finally { base.Finalize(); } }}

Page 18: CLR Exception Handing And Memory Management

Finalizers (2)Finalizers (2) Only implement Finalize on objects Only implement Finalize on objects

that need finalizationthat need finalization Finalization is only appropriate for Finalization is only appropriate for

cleanup of unmanaged resourcescleanup of unmanaged resources Keeps objects alive an order of Keeps objects alive an order of

magnitude longermagnitude longer Free any external resources you own Free any external resources you own

in your Finalize methodin your Finalize method Do not throw exceptions in finalizersDo not throw exceptions in finalizers

The rest of your finalizer will not run The rest of your finalizer will not run Check out Critical Finalizers in 2.0Check out Critical Finalizers in 2.0

Brad Abrams
Add info about calling GC.Collect()
Page 19: CLR Exception Handing And Memory Management

Finalizers (3)Finalizers (3)

Do not block or wait in finalizersDo not block or wait in finalizers All finalization for that process could be All finalization for that process could be

stoppedstopped Only release resources that are held Only release resources that are held

onto by this instanceonto by this instance Do not reference other instancesDo not reference other instances Will be called on one or more Will be called on one or more

different threadsdifferent threads

Page 20: CLR Exception Handing And Memory Management

Dispose PatternDispose Pattern

Implement the dispose pattern Implement the dispose pattern whenever you have a finalizerwhenever you have a finalizer Gives developers explicit controlGives developers explicit control

Free any disposable resources your Free any disposable resources your type owns in the type owns in the Dispose()Dispose() method method Not just the external resourcesNot just the external resources Propagate calls to Propagate calls to Dispose()Dispose() through through

containment hierarchiescontainment hierarchies

Page 21: CLR Exception Handing And Memory Management

Dispose Pattern (2)Dispose Pattern (2) Suppress finalization once Suppress finalization once Dispose()Dispose() has has

been calledbeen called Dispose()Dispose() should be callable multiple should be callable multiple

times without throwing an exceptiontimes without throwing an exception The method will do nothing after the first callThe method will do nothing after the first call After After Dispose()Dispose() is called other methods on is called other methods on

the class can throw ObjectDisposedException the class can throw ObjectDisposedException Do not assume that Do not assume that Dispose() Dispose() will be calledwill be called

For unmanaged cleanup have a finalizer as wellFor unmanaged cleanup have a finalizer as well Do call your base class’s Do call your base class’s Dispose(bool)Dispose(bool)

method if it implements IDisposablemethod if it implements IDisposable

Page 22: CLR Exception Handing And Memory Management

Implementing Implementing IDisposableIDisposable

public class Resource: IDisposable { private bool disposed = false; pubic int GetValue () { if (disposed) throw new ObjectDisposedException(); // do work } public void Dispose() { if (disposed) return; Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { // Dispose dependent objects disposed = true; } // Free unmanaged resources } ~Resource() { Dispose(false); }}

public class Resource: IDisposable { private bool disposed = false; pubic int GetValue () { if (disposed) throw new ObjectDisposedException(); // do work } public void Dispose() { if (disposed) return; Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { // Dispose dependent objects disposed = true; } // Free unmanaged resources } ~Resource() { Dispose(false); }}

Page 23: CLR Exception Handing And Memory Management

Using StatementUsing Statement Acquire, Execute, Release patternAcquire, Execute, Release pattern Works with any IDisposable objectWorks with any IDisposable object

Data access classes, streams, text Data access classes, streams, text readers and writers, network classes, readers and writers, network classes, etc.etc.using (Resource res = new Resource()) {

res.DoWork();}

using (Resource res = new Resource()) { res.DoWork();} Resource res = new Resource(...);

try { res.DoWork();}finally { if (res != null)

((IDisposable)res).Dispose();}

Resource res = new Resource(...);try { res.DoWork();}finally { if (res != null)

((IDisposable)res).Dispose();}

Page 24: CLR Exception Handing And Memory Management

Using StatementUsing Statement Acquire, Execute, Release patternAcquire, Execute, Release pattern Works with any IDisposable objectWorks with any IDisposable object

Data access classes, streams, text Data access classes, streams, text readers and writers, network classes, readers and writers, network classes, etc.etc.Using res As Resource = New Resource ()

res.DoWork()End Using

Using res As Resource = New Resource () res.DoWork()End Using Dim res As New Resource()

Try res.DoWork()Finally If res IsNot Nothing Then CType(res, IDisposable).Dispose() End IfEnd Try

Dim res As New Resource()Try res.DoWork()Finally If res IsNot Nothing Then CType(res, IDisposable).Dispose() End IfEnd Try

Page 25: CLR Exception Handing And Memory Management

Using Statement (2)Using Statement (2) Can you find the “bug” in this code?Can you find the “bug” in this code? Will input and output always be Will input and output always be

closed?closed?static void Copy(string sourceName, string destName) { Stream input = File.OpenRead(sourceName); Stream output = File.Create(destName); byte[] b = new byte[65536]; int n; while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n); } output.Close(); input.Close();}

static void Copy(string sourceName, string destName) { Stream input = File.OpenRead(sourceName); Stream output = File.Create(destName); byte[] b = new byte[65536]; int n; while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n); } output.Close(); input.Close();}

Page 26: CLR Exception Handing And Memory Management

Using Statement (3)Using Statement (3) static void Copy(string sourceName, string destName) { Stream input = File.OpenRead(sourceName); Stream output = File.Create(destName); try { byte[] b = new byte[65536]; int n; while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n); } } finally { output.Close(); input.Close(); }}

static void Copy(string sourceName, string destName) { Stream input = File.OpenRead(sourceName); Stream output = File.Create(destName); try { byte[] b = new byte[65536]; int n; while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n); } } finally { output.Close(); input.Close(); }}

Page 27: CLR Exception Handing And Memory Management

Using Statement (4)Using Statement (4)static void Copy(string sourceName, string destName) { Stream input = File.OpenRead(sourceName); try { Stream output = File.Create(destName); try { byte[] b = new byte[65536]; int n; while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n); } } finally { output.Close(); } } finally { input.Close(); }}

static void Copy(string sourceName, string destName) { Stream input = File.OpenRead(sourceName); try { Stream output = File.Create(destName); try { byte[] b = new byte[65536]; int n; while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n); } } finally { output.Close(); } } finally { input.Close(); }}

Page 28: CLR Exception Handing And Memory Management

Using Statement (4)Using Statement (4) Code is correct and much more Code is correct and much more

readable with using statementsreadable with using statements Types should implement Types should implement

IDisposable to take advantage of IDisposable to take advantage of this supportthis support

static void Copy(string sourceName, string destName) { using (Stream input = File.OpenRead(sourceName)) using (Stream output = File.Create(destName)) { byte[] b = new byte[65536]; int n; while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n); } }}

static void Copy(string sourceName, string destName) { using (Stream input = File.OpenRead(sourceName)) using (Stream output = File.Create(destName)) { byte[] b = new byte[65536]; int n; while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n); } }}

Page 29: CLR Exception Handing And Memory Management

Resource Management Resource Management 2.0 Feature: 2.0 Feature:

MemoryPressureMemoryPressure GC.AddMemoryPressure ( int GC.AddMemoryPressure ( int

pressure )pressure ) Useful when you have a disproportionate Useful when you have a disproportionate

ratio of managed, to unmanaged ratio of managed, to unmanaged resourcesresources

GC alters it’s strategy, to increase the GC alters it’s strategy, to increase the number of collections performednumber of collections performed

GC.RemoveMemoryPressure when your GC.RemoveMemoryPressure when your object is freed, to allow the GC to return object is freed, to allow the GC to return to its standard strategyto its standard strategy

Page 30: CLR Exception Handing And Memory Management

Resource Management Resource Management 2.0 Feature: 2.0 Feature:

MemoryPressureMemoryPressureclass Bitmap {

private long _size;Bitmap (string path ) { _size = new FileInfo(path).Length; GC.AddMemoryPressure(_size); // other work}~Bitmap() { GC.RemoveMemoryPressure(_size);

// other work}

}

class Bitmap {private long _size;Bitmap (string path ) { _size = new FileInfo(path).Length; GC.AddMemoryPressure(_size); // other work}~Bitmap() { GC.RemoveMemoryPressure(_size);

// other work}

}

Page 31: CLR Exception Handing And Memory Management

Resource Management Resource Management 2.0 Feature: 2.0 Feature:

HandleCollectorHandleCollector HandleCollector keeps track of a limited number of HandleCollector keeps track of a limited number of

handles handles typically, unmanaged resource handles: HDCs, HWnds, etctypically, unmanaged resource handles: HDCs, HWnds, etc

When you allocate a new handle, call Add. When you allocate a new handle, call Add. When you freeing, call RemoveWhen you freeing, call Remove As you add to the collector, it may perform a As you add to the collector, it may perform a

GC.Collect(), to free existing handles, based on the GC.Collect(), to free existing handles, based on the current count, and the number of resources availablecurrent count, and the number of resources available

namename: allows you to track each handle type separately, if needed: allows you to track each handle type separately, if neededinitialThresholdinitialThreshold: the point at which collections should begin being : the point at which collections should begin being

performedperformedmaximumThresholdmaximumThreshold: the point at which collections MUST be : the point at which collections MUST be

performed. This should be set to the maximum number of available performed. This should be set to the maximum number of available handleshandles

HandleCollector(string name, int initialThreshold, int maximumThreshold);

HandleCollector(string name, int initialThreshold, int maximumThreshold);

Page 32: CLR Exception Handing And Memory Management

Resource Management Resource Management 2.0 Feature: 2.0 Feature:

HandleCollectorHandleCollectorstatic readonly HandleCollector GdiHandleType =

new HandleCollector( “GdiHandles”, 10, 50);

static IntPtr CreateSolidBrush() {IntPtr temp = CreateSolidBrushImpl(…);GdiHandleType.Add();return temp;

}

internal static void DeleteObject(IntPtr handle) {DeleteObjectImpl(handle);GdiHandleType.Remove();

}

static readonly HandleCollector GdiHandleType = new HandleCollector( “GdiHandles”, 10, 50);

static IntPtr CreateSolidBrush() {IntPtr temp = CreateSolidBrushImpl(…);GdiHandleType.Add();return temp;

}

internal static void DeleteObject(IntPtr handle) {DeleteObjectImpl(handle);GdiHandleType.Remove();

}

Page 33: CLR Exception Handing And Memory Management

More InformationMore Information

My Blog: My Blog: http://blogs.msdn.com/bradahttp://blogs.msdn.com/brada

The SLAR

Designing .NET Class Libraries: http://msdn.microsoft.com/netframework/programming/classlibraries/

FxCop is your ally in the fight: http://www.gotdotnet.com/team/fxcop/ .NET Framework Resource Management whitepaperResource Management with the CLR: The IDisposable Pattern

Special thanks to Brian Harry for significant input in the exceptions section

Applied Microsoft .NET Framework Programming

Page 34: CLR Exception Handing And Memory Management

Back upBack up

Page 35: CLR Exception Handing And Memory Management

Intro to Exception Handling Intro to Exception Handling in VBin VB

VB .NET has structured Exception HandlingVB .NET has structured Exception Handling

TryTry

Obj.DoSomeWorkObj.DoSomeWork

Catch e As ExceptionCatch e As Exception

LogError(e)LogError(e)

FinallyFinally

Obj.DisposeObj.Dispose

End TryEnd Try Can “Throw” an exceptionCan “Throw” an exception

Throw New System.Exception(“Error Message”)Throw New System.Exception(“Error Message”) Enhanced Exception objectEnhanced Exception object

Tracks nested exceptionsTracks nested exceptions Provides StackTrace to help pinpoint errorProvides StackTrace to help pinpoint error

Page 36: CLR Exception Handing And Memory Management

Try '<code that may fail> Catch ex As Exception '<error handling code>

Finally '<clean up>End Try

fReRaise = False

OnError GoTo ErrHandler '<code that may fail> GoTo CleanUp

ErrHandler: If '<condition we can handle> Then '<error handling code> Else fReRaise = True End If

CleanUp: If fReRaise Then Err.Raise errNum

On Error vs. On Error vs. Try/Catch/FinallyTry/Catch/Finally

OnError GoTo ErrHandler '<code that may fail>

ErrHandler: If '<condition we can handle> Then '<error handling code>

fReRaise = FalseTry '<code that may fail>

Else fReRaise = True End IfCleanUp: If fReRaise Then Err.Raise errNum

Catch ex As Exception '<error handling code>Finally '<clean up>

Page 37: CLR Exception Handing And Memory Management

VB 2005 Exception VB 2005 Exception SupportSupport Exception AssistantException Assistant

A dialog pops up when an exception occurs in your application that A dialog pops up when an exception occurs in your application that describes the exception type and the common ways reasons for it describes the exception type and the common ways reasons for it being thrown. You can set any exception type you like to be a “first being thrown. You can set any exception type you like to be a “first chance exception” which would bring up the dialog in the first chance exception” which would bring up the dialog in the first place it encountered this exception via the DebugàExceptions place it encountered this exception via the DebugàExceptions menus.  menus.  

Overlapping Exception Warnings Overlapping Exception Warnings VB warns when you’ve caught a supertype exception before its VB warns when you’ve caught a supertype exception before its

subtype (thus indicating dead code.)subtype (thus indicating dead code.) IDispose spitIDispose spit

Visual Basic will now spit the IDisposable pattern when you type Visual Basic will now spit the IDisposable pattern when you type Implements IDispose and commit.  Implements IDispose and commit.  

Unhandled Exception eventUnhandled Exception event VB now has application events which you can access by opening VB now has application events which you can access by opening

the app designer, selecting the “view application events” button, the app designer, selecting the “view application events” button, and using the drop downs to navigate to the UnhandledException and using the drop downs to navigate to the UnhandledException event. event.

Using statement Using statement In 2005, VB will support it too. In 2005, VB will support it too.

Application tracing Application tracing VB now supports an extremely easy way to do application logging. VB now supports an extremely easy way to do application logging.

Just type My.Application.Log.WriteException() and go from there…Just type My.Application.Log.WriteException() and go from there…

Page 38: CLR Exception Handing And Memory Management

Using Exceptions: Using Exceptions: Creating new Exceptions Creating new Exceptions

(continued)(continued) Every exception should have at Every exception should have at least the top three constructorsleast the top three constructors

public class XxxException : YyyException { public XxxException () {} public XxxException (string message) {} public XxxException (string message,

Exception inner) {} protected XxxException (

SerializationInfo info,StreamingContext context) {}

}

public class XxxException : YyyException { public XxxException () {} public XxxException (string message) {} public XxxException (string message,

Exception inner) {} protected XxxException (

SerializationInfo info,StreamingContext context) {}

}

Note: making an exception fully Note: making an exception fully serializable implies a little more work…serializable implies a little more work…

Page 39: CLR Exception Handing And Memory Management

Using Exceptions: Bad Using Exceptions: Bad PracticePractice

ArgumentNullException does not follow ArgumentNullException does not follow this patternthis pattern

Justification: Argument names are much Justification: Argument names are much more common than messagemore common than message

public class ArgumentNullException : ArgumentException {

public ArgumentNullException () {} public ArgumentNullException (string paramName) {} public ArgumentNullException (string paramName,

string message) {}}

public class ArgumentNullException : ArgumentException {

public ArgumentNullException () {} public ArgumentNullException (string paramName) {} public ArgumentNullException (string paramName,

string message) {}}

Page 40: CLR Exception Handing And Memory Management

Using Exceptions: Bad Using Exceptions: Bad PracticePractice

Result: Habit wins out and people Result: Habit wins out and people commonly type:commonly type:throw new ArgumentNullException ("the value must

pass an employee name");

throw new ArgumentNullException ("the value must pass an employee name");

throw new ArgumentNullException ("Name", "the value must pass an employee name");

throw new ArgumentNullException ("Name", "the value must pass an employee name");

Unhandled Exception: System.ArgumentNullException: Value cannot be null.Parameter name: the value must pass an employee name

Unhandled Exception: System.ArgumentNullException: Value cannot be null.Parameter name: the value must pass an employee name

• Rather than:

• We end up with odd error messages such as:

• Lesson: Just follow the pattern!