First we demonstrate what happens when errors arise in a console application that does not use exception handling. Figure 12.1 inputs two integers from the user, then divides the first integer by the second using integer division to obtain an int result. In this example, we will see that an exception is thrown (i.e., an exception occurs) when a method detects a problem and is unable to handle it.
Figure 12.1. Integer division without exception handling.
1 // Fig. 12.1: DivideByZeroNoExceptionHandling.cs 2 // An application that attempts to divide by zero. 3 using System; 4 5 class DivideByZeroNoExceptionHandling 6 { 7 static void Main() 8 { 9 // get numerator and denominator 10 Console.Write( "Please enter an integer numerator: " ); 11 int numerator = Convert.ToInt32( Console.ReadLine() ); 12 Console.Write( "Please enter an integer denominator: " ); 13 int denominator = Convert.ToInt32( Console.ReadLine() ); 14 15 // divide the two integers, then display the result 16 int result = numerator / denominator; 17 Console.WriteLine( " Result: {0:D} / {1:D} = {2:D}", 18 numerator, denominator, result ); 19 } // end Main 20 } // end class DivideByZeroNoExceptionHandling
|
Running the Application
In most of the examples we have created so far, the application appears to run the same with or without debugging. As we discuss shortly, the example in Fig. 12.1 might cause errors, depending on the user's input. If you run this application using the Debug > Start Debugging menu option, the program pauses at the line where an exception occurs and displays the Exception Assistant, allowing you to analyze the current state of the program and debug it. We discuss the Exception Assistant in Section 12.4.3. We discuss debugging in detail in Appendix C.
In this example, we do not wish to debug the application; we simply want to see what happens when errors arise. For this reason, we execute this application from a Command Prompt window. Select Start > All Programs > Accessories > Command Prompt to open a Command Prompt window, then use the cd command to change to the application's Debug directory. For example, if this application resides in the directory C:examplesch12Fig12_01DivideByZeroNoExceptionHandling on your system, you would type
cd /d C:examplesch12Fig12_01DivideByZeroNoExceptionHandling inDebug
in the Command Prompt, then press Enter to change to the application's Debug directory. To execute the application, type
DivideByZeroNoExceptionHandling.exe
in the Command Prompt, then press Enter. If an error arises during execution, a dialog is displayed indicating that the application has encountered a problem and needs to close. The dialog also asks whether you'd like to send information about this error to Microsoft. Since we are creating this error for demonstration purposes, you should click Don't Send. [Note: On some systems a Just-In-Time Debugging dialog is displayed instead. If this occurs, simply click the No button to dismiss the dialog.] At this point, an error message describing the problem is displayed in the Command Prompt. We formatted the error messages in Fig. 12.1 for readability. [Note: Selecting Debug > Start Without Debugging (or F5) to run the application from Visual Studio executes the application's so-called release version. The error messages produced by this version of the application may differ from those shown in Fig. 12.1 due to optimizations that the compiler performs to create an application's release version.]
Analyzing the Results
The first sample execution in Fig. 12.1 shows a successful division. In the second sample execution, the user enters 0 as the denominator. Note that several lines of information are displayed in response to the invalid input. This informationknown as a stack traceincludes the exception name (System.DivideByZeroException) in a descriptive message indicating the problem that occurred and the path of execution that led to the exception, method by method. This information helps you debug a program. The first line of the error message specifies that a DivideByZeroException has occurred. When division by zero in integer arithmetic occurs, the CLR throws a DivideByZeroException (namespace System). The text after the name of the exception, "Attempted to divide by zero," indicates that this exception occurred as a result of an attempt to divide by zero. Division by zero is not allowed in integer arithmetic. [Note: Division by zero with floating-point values is allowed. Such a calculation results in the value infinity, which is represented by either constant Double.PositiveInfinity or constant Double.NegativeInfinity, depending on whether the numerator is positive or negative. These values are displayed as Infinity or -Infinity. If both the numerator and denominator are zero, the result of the calculation is the constant Double.NaN ("not a number"), which is returned when a calculation's result is undefined.]
Each "at" line in the stack trace indicates a line of code in the particular method that was executing when the exception occurred. The "at" line contains the namespace, class name and method name in which the exception occurred (DivideByZeroNoExceptionHandling.Main), the location and name of the file in which the code resides (C:examplesch12Fig12_01DivideByZeroNoExceptionHandlingDivideByZeroNoException Handling.cs:line 16) and the line of code where the exception occurred. In this case, the stack trace indicates that the DivideByZeroException occurred when the program was executing line 16 of method Main. The first "at" line in the stack trace indicates the exception's throw pointthe initial point at which the exception occurred (i.e., line 16 in Main). This information makes it easy for the programmer to see where the exception originated, and what method calls were made to get to that point in the program.
Now, let's look at a more detailed stack trace. In the third sample execution, the user enters the string "hello" as the denominator. This causes a FormatException, and another stack trace is displayed. Our earlier examples that read numeric values from the user assumed that the user would input an integer value. However, a user could erroneously input a noninteger value. A FormatException (namespace System) occurs, for example, when Convert method ToInt32 receives a string that does not represent a valid integer. Starting from the last "at" line in the stack trace, we see that the exception was detected in line 13 of method Main. The stack trace also shows the other methods that led to the exception being thrownConvert.ToInt32, Number.ParseInt32 and Number.StringToNumber. To perform its task, Convert.ToInt32 calls method Number.ParseInt32, which in turn calls Number.StringToNumber. The throw point occurs in Number.StringToNumber, as indicated by the first "at" line in the stack trace.
Note that in the sample executions in Fig. 12.1, the program also terminates when exceptions occur and stack traces are displayed. This does not always happensometimes a program may continue executing even though an exception has occurred and a stack trace has been printed. In such cases, the application may produce incorrect results. The next section demonstrates how to handle exceptions to enable the program to run to normal completion.
Preface
Index
Introduction to Computers, the Internet and Visual C#
Introduction to the Visual C# 2005 Express Edition IDE
Introduction to C# Applications
Introduction to Classes and Objects
Control Statements: Part 1
Control Statements: Part 2
Methods: A Deeper Look
Arrays
Classes and Objects: A Deeper Look
Object-Oriented Programming: Inheritance
Polymorphism, Interfaces & Operator Overloading
Exception Handling
Graphical User Interface Concepts: Part 1
Graphical User Interface Concepts: Part 2
Multithreading
Strings, Characters and Regular Expressions
Graphics and Multimedia
Files and Streams
Extensible Markup Language (XML)
Database, SQL and ADO.NET
ASP.NET 2.0, Web Forms and Web Controls
Web Services
Networking: Streams-Based Sockets and Datagrams
Searching and Sorting
Data Structures
Generics
Collections
Appendix A. Operator Precedence Chart
Appendix B. Number Systems
Appendix C. Using the Visual Studio 2005 Debugger
Appendix D. ASCII Character Set
Appendix E. Unicode®
Appendix F. Introduction to XHTML: Part 1
Appendix G. Introduction to XHTML: Part 2
Appendix H. HTML/XHTML Special Characters
Appendix I. HTML/XHTML Colors
Appendix J. ATM Case Study Code
Appendix K. UML 2: Additional Diagram Types
Appendix L. Simple Types
Index