Error handling in all Supported Languages within the .Net framework is now provide by a Structured Exception Handling mechanism. Obviously all program development will encounter errors during run time. Normally the application tries to do for instance a file open or read on an object and that operation fails for some reason or other. How do we handle this situation? Classically the approach to such a failure has been to look at a return value from the API call itself, in C++ for example this could be a NULL or 0 for success and some other value both positive or negative to indicate an error. However, some of th API call would send back a value if no error for instance the handle for a create Window call and a NULL only if the creation failed. So we were faced with a non standard approach!
Other languages tried other techniques, the classic example of a non structured technique was VB and its infamous On Error Goto . This was probably the biggest mistake in any language, GoTo has no place in a modern software development environment, it harks back to the spaghetti programming era of the 1970's.
C++ and Java have offered a structured exception technique for many years, however the problem was that the mechanism was language specific. Microsoft during the late 1990' enhanced the COM (Common Object Model) in an attempt to provide a suitable cross language structured exception model but as with most aspects of COM the complexity of the technique made implementation difficult.
The .NET framework through the CLR has standardised the structured exception handling across the Supported Languages. Any unhandled exceptions simply closes down the application, this forces the developer to consider error handling from day 1. The mechanism is very simple, in much the same way structured exceptions were handled in C++ the function reporting the error will place the error information into an object. Unlike C++ the object is now within the CLR and hence is of a standard format giving the developer only a single learning curve and cross language consistency.
We can view the syntax for structured exception handling by looking at one of the example programs in C#
private void PrintPreview()
{
try
{
PrintPreviewDialog prevDlg;
prevDlg = new PrintPreviewDialog();
prevDlg.Document = printDocument;
prevDlg.Size = new System.Drawing.Size(600, 329);
prevDlg.ShowDialog();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
When this function executes and the code enters the Try block the CLR will write a so called exception
block to the application stack. If a lower level function then throws an exception the CLR structured handler will search back up the block
until this exception block is found. The CLR will then unwind the stack up to this level and transfer exception handling to this try block.
Exceptions can be thrown from any level so structured handlers can be nested, in taking the nested approach the stack will only be unwound to the appropriate
handler. In the above example we are using the default exception object, a more specific object can be created by
creating the object from the System.Exception object. By setting the properties of this application specific
object it is possible to catch specific exceptions.
An example of defining your own exception object could look like. in this case in VB.NET
Dim NewException as New Exception("this is looking for new types of exception")
'' Set the source
NewException.Source = "Understanding Structured Exceptions"
As we have seen the stack is discarded between were the exception is detected and the handler,
Objects used in between these two points are therefore discarded, the Automatic Garbage Collection
will of course dispose of these resources but the application does not get the option of using
the objects disposal methods which may be a problem. The Dispose will of course be called during the Automatic garbage collection but the
method may be meaningless at this time. To counter this problem you can use the Try - Finally
mechanism instead. In this structure the code in the Finally is executed during the stack unwind.
private void PrintPreview()
{
try
{
PrintPreviewDialog prevDlg;
prevDlg = new PrintPreviewDialog();
prevDlg.Document = printDocument;
prevDlg.Size = new System.Drawing.Size(600, 329);
prevDlg.ShowDialog();
}
Finally
{
MessageBox.Show(" Execute the Finally block ");
}
}
This is the syntax of the previous example using a Finally block. In fact we can combine the Try - Catch - Finally giving a structure of the form
private void PrintPreview()
{
try
{
PrintPreviewDialog prevDlg;
prevDlg = new PrintPreviewDialog();
prevDlg.Document = printDocument;
prevDlg.Size = new System.Drawing.Size(600, 329);
prevDlg.ShowDialog();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
Finally
{
MessageBox.Show(" Execute the Finally block ");
}
}
Automatic Garbage Collection