developer.com
Search EarthWeb
CodeGuru | Gamelan | Jars | Wireless | Discussions
Navigate developer.com
Architecture & Design  
Database  
Java
Languages & Tools
Microsoft & .NET
Open Source  
Project Management  
Security  
Techniques  
Voice  
Web Services  
Wireless/Mobile
XML  
New
 
Technology Jobs  

   Developer.com Webcasts:
  The Impact of Coding Standards and Code Reviews

  Project Management for the Developer

  Defining Your Own Software Development Methodology

  more Webcasts...




See the Winners!




Developer Jobs

Be a Commerce Partner














 


Developer News -
Jim Zemlin: The New Center of Linux Gravity    August 21, 2008
Microsoft's Novell Investment Tops $340M    August 20, 2008
Fedora 10 Takes Shape    August 19, 2008
IBM Gives a Mobile Voice to Developers    August 18, 2008
Free Tech Newsletter -

What!? A .NET Application Can Die?
By John Robbins

Go to page: 1  2  Next  

You have to love .NET. All those nasty crash problems we used to wrestle with in Win32 are now just stories we can tell around the virtual campfire. No longer will our users have to see that ugly crash dialog telling them oh so subtly that we programmers screwed up. Life it .NET is great, isn't it?

The prior paragraph was somewhat of a dream sequence. While .NET does keep us from messing with all the hassles of memory corruptions and such, as we all know, reality is a little different. As we've all seen a million times when learning .NET, your applications can certainly end sadly and abruptly. While that's fine during development, we certainly don't want to have our .NET applications die with an exception in front of our users. Nothing is more embarrassing than a confusing dialog or web page referring to unhandled exceptions.

In this column, I want to discuss how to set exception handlers in your .NET applications so you can apologize to the user for abruptly terminating and also gather more information about the unhandled exception so you can stand a chance of duplicating the problem so you can fix it. Back in the Win32 days, it was relatively easy to make a single function call, SetUnhandledExceptionFilter, so you could set a function that would get called no matter what thread caused an exception in your application. While .NET allows the same type of handling, it's got a twist in that console, WinForms, and ASP.NET applications all set up the exception handlers differently. Additionally, there's different behavior depending on which type of thread caused the exception.

After showing you the thread types, I'll discuss setting exception handling in console applications. Part of that discussion will be a small program that shows you how exceptions are reported depending on which thread type has the unhandled exception. Once past the console applications, I'll turn to WinForms applications. Finally, I'll cover ASP.NET applications.

Thread Types

As how the exception handling gets called is dependent on which thread type is causing the exception, its important that I list them. That way you'll see the ramifications when running the ConsoleException program later in the column.

  • Main Thread
    The initial thread of the console or GUI application.
  • Manual Thread
    Threads created with System.Threading.Thread.
  • Pool Thread
    Threads created with System.Threading.ThreadPool or System.Threading.Timer. Used quite a bit in the CLR
  • Finalizer Thread
    The garbage collector thread
  • Unmanaged Thread
    Win32 threads not created by the CLR.

Unhandled Exceptions in Console Applications

The .NET documentation is quite straight forward in pointing out that to handle exceptions for an Application Domain you'll set a System.UnhandledExceptionEventHandler delegate to the AppDomain.CurrentDomain.UnhandledException event like the following:

using System;

namespace SimpleEX
{
  class Class1
  {
    static void Main ( )
    {
      AppDomain.CurrentDomain.UnhandledException += 
              new UnhandledExceptionEventHandler(SimpleHandler);
              
      String x = null ;
      Console.WriteLine ( x.ToString ( ) ) ;     
    }
    
    static void SimpleHandler(Object                      Sender,
                              UnhandledExceptionEventArgs Args  )
    {
      Exception e = (Exception)Args.ExceptionObject ;
      Console.WriteLine ( "Caught : " + e.Message ) ;
    }                                   
  }
}

While setting your exception handler looks relatively straight forward, there's a couple of key "gotchas" that you need to keep in mind. The first is if you are creating other Application Domains in your code, you can only set the exception handler when executing in an Application Domain. You can't set exception handlers from outside the Application Domain.

The second issue is related to the threads I discussed earlier. If the exception occurs in the main thread, your application will terminate after your exception handler returns. However, if the exception occurs in any other thread, that particular thread will terminate, but the main thread will continue to execute as if nothing happened.

When I first ran across the fact that the main thread continues to execute, I was a little perplexed as I would have thought that the application terminated on any thread. .NET is quite a bit different from Win32, and here's yet another example of where bringing assumptions proves you wrong. If you want to treat any exception as fatal, no matter which thread it comes from, you can call the Environment.Exit method, which will end your application from inside your exception handler.

Inside your exception handler, the UnhandledExceptionEventArgs parameter has a read only property, IsTerminating, which when true, reports that the application is ending. As you'd expect you'll only see the IsTerminating set to true when the main thread has the exception. If the value is false, the thread is terminating, but not the application.

To show you exceptions in each of the managed threads, I whipped together ConsoleExceptions. This program does nothing more than let you easily play with setting an exception handler and dictating which thread type where you want to throw an exception. The command line options are as follows:

Command line options y|n m|t|p|g
You must specify if you want the error handler and which error
  y = install unhandled error handler
  n = use default error handler

  m = main thread
  t = managed thread
  p = pool thread
  g = garbage collector

If you'd like to see what happens when you have an error handler and an exception occurs in the garbage collector thread, the command line is "y g". The main thread has a finallyblock as well as a call to Console.WriteLine to tell you when the application ends. I'd encourage you to play with the various threads and how exceptions are handled in them so you'll be able to properly handle unhandled exceptions occur in your applications.

Go to page: 1  2  Next  


Tools:
Add www.developer.com to your favorites
Add www.developer.com to your browser search box
IE 7 | Firefox 2.0 | Firefox 1.5.x
Receive news via our XML/RSS feed


Visual C++ Archives








JupiterOnlineMedia

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info


Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers