Вы находитесь на странице: 1из 5

Osman Khalid, Lecturer, Computer Sciences Department, COMSATS Institute of Information Technology

Lecture (24 Dec)

Errors and Exceptions


Nested try Blocks One nice feature of exceptions is that you can nest try blocks inside each other, like this:
try { // Point A try { // Point B } catch { // Point C } finally { // clean up } // Point D } catch { // error handling } finally { // clean up }

If an exception is thrown inside the outer try block but outside the inner try block (points A and D), the situation is no different from any of the scenarios you have seen before: either the exception is caught by the outer catch block and the outer finally block is executed, or the finally block is executed and the .NET runtime handles the exception. If an exception is thrown in the inner try block (point B), and there is a suitable inner catch block to handle the exception, then, again, you are in familiar territory: the exception is handled there, and the inner finally block is executed before execution resumes inside the outer try block (at point D). Now suppose that an exception occurs in the inner try block, but there isn t a suitable inner catch block to handle it. This time, the inner finally block is executed as usual, but then the .NET runtime will have no choice but to leave the entire inner try block in order to search for a suitable exception handler.The next obvious place to look is in the outer catch block. If the system finds one here, then that handler will be executed and then the

Downloaded from: www.onspot.pk

Osman Khalid, Lecturer, Computer Sciences Department, COMSATS Institute of Information Technology

outer finally block will be executed after. If there is no suitable handler here, the search for one will go on. In this case, it means the outer finally block will be executed, and then, because there are no more catch blocks, control will be transferred to the .NET runtime. Note that at no point is the code beyond point D in the outer try block executed. An even more interesting thing happens if an exception is thrown at point C. If the program is at point C, it must be already processing an exception that was thrown at point B. It is quite legitimate to throw another exception from inside a catch block. In this case, the exception is treated as if it had been thrown by the outer try block, so flow of execution will immediately leave the inner catch block, and execute the inner finally block, before the system searches the outer catch block for a handler. Similarly, if an exception is thrown in the inner finally block, control will immediately be transferred to the best appropriate handler, with the search starting at the outer catch block. It is perfectly legitimate to throw exceptions from catch and finally blocks. Although the situation has been shown with just two try blocks, the same principles hold no matter how many try blocks you nest inside each other. At each stage, the .NET runtime will smoothly transfer control up through the try blocks, looking for an appropriate handler. At each stage, as control leaves a catch block, any cleanup code in the corresponding finally block (if present) will be executed, but no code outside any finally block will be run until the correct catch handler has been found and run. The nesting of try blocks can also occur between methods themselves. For example, if method A calls method B from within a try block, then method B itself has a try block within it as well USER DEFINED EXCEPTIONS EXAMPLE
using System; using System.IO; namespace Wrox.ProCSharp.AdvancedCSharp { class MainEntryPoint { static void Main() { string fileName; Console.Write("Please type in the name of the file " + "containing the names of the people to be cold-called > "); fileName = Console.ReadLine(); ColdCallFileReader peopleToRing = new ColdCallFileReader(); try {

Downloaded from: www.onspot.pk

Osman Khalid, Lecturer, Computer Sciences Department, COMSATS Institute of Information Technology

peopleToRing.Open(fileName); for (int i=0 ; i<peopleToRing.NPeopleToRing; i++) { peopleToRing.ProcessNextPerson(); } Console.WriteLine("All callees processed correctly"); } catch(FileNotFoundException e) { Console.WriteLine("The file {0} does not exist", fileName); } catch(ColdCallFileFormatException e) { Console.WriteLine( "The file {0} appears to have been corrupted", fileName); Console.WriteLine("Details of problem are: {0}", e.Message); if (e.InnerException != null) Console.WriteLine( "Inner exception was: {0}", e.InnerException.Message); } catch(Exception e) { Console.WriteLine("Exception occurred:\n" + e.Message); } finally { peopleToRing.Dispose(); } Console.ReadLine(); } } class ColdCallFileReader :IDisposable { FileStream fs; StreamReader sr; uint nPeopleToRing; bool isDisposed = false; bool isOpen = false; public void Open(string fileName) { if (isDisposed) throw new ObjectDisposedException("peopleToRing"); fs = new FileStream(fileName, FileMode.Open); sr = new StreamReader(fs); try { string firstLine = sr.ReadLine(); nPeopleToRing = uint.Parse(firstLine); isOpen = true; } catch (FormatException e) { throw new ColdCallFileFormatException(

Downloaded from: www.onspot.pk

Osman Khalid, Lecturer, Computer Sciences Department, COMSATS Institute of Information Technology

"First line isn\'t an integer", e); } } public uint NPeopleToRing { get { if (isDisposed) throw new ObjectDisposedException("peopleToRing"); if (!isOpen) throw new UnexpectedException( "Attempt to access cold call file that is not open"); return nPeopleToRing; } } public void Dispose() { if (isDisposed) return; isDisposed = true; isOpen = false; if (fs != null) { fs.Close(); fs = null; } } public void ProcessNextPerson() { if (isDisposed) throw new ObjectDisposedException("peopleToRing"); if (!isOpen) throw new UnexpectedException( "Attempt to access cold call file that is not open"); try { string name; name = sr.ReadLine(); if (name == null) throw new ColdCallFileFormatException("Not enough names"); if (name[0] == 'Z') { throw new SalesSpyFoundException(name); } Console.WriteLine(name); } catch(SalesSpyFoundException e) { Console.WriteLine(e.Message); } finally

Downloaded from: www.onspot.pk

Osman Khalid, Lecturer, Computer Sciences Department, COMSATS Institute of Information Technology

{ } } } class SalesSpyFoundException : ApplicationException { public SalesSpyFoundException(string spyName) : base("LandLine spy found, with name " + spyName) { } public SalesSpyFoundException(string spyName, Exception innerException) : base("LandLine spy found, with name " + spyName, innerException) { } } class ColdCallFileFormatException : ApplicationException { public ColdCallFileFormatException(string message) : base(message) { } public ColdCallFileFormatException(string message, Exception innerException) : base(message, innerException) { } } class UnexpectedException : ApplicationException { public UnexpectedException(string message) : base(message) { } public UnexpectedException(string message, Exception innerException) : base(message, innerException) { } } }

Downloaded from: www.onspot.pk

Вам также может понравиться