Blog Archives

Exceptions (part 3, advanced)

For Windows Forms and WPF we have specific exceptions to deal with. Actually these are not really exceptions. They are events, which are raised whenever any unhandled exception occurs. “Unhandled” means there is nothing that catches exceptions and the entire stack did not come up with any solution. Nothing stopped the thread falling down to its lowest level, and even that level does not know what to do with the exception. You can eg. throw an exception on a button click to cause this behavior.
These events allow applications to log information about unhandled exceptions.

In Windows Forms the EventHandler is defined in System.Threading and is called ThreadExceptionEventHandler. If you do not define this event call then your application will crash when unhandled exceptions show up.

[STAThread]
static void Main() {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.ThreadException += Application_ThreadException;
    Application.Run(new Form1());
} //

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) {
    Exception lException = (Exception)e.Exception;
    MessageBox.Show(lException.Message);
} //

The approach in WPF is similar. We are talking in Domains. Therefore we subscribe to AppDomain.CurrentDomain.UnhandledException .

public MainWindow() {
    InitializeComponent();
    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;            
} //

void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
    Exception lException = (Exception)e.ExceptionObject;
    MessageBox.Show(lException.Message + "\nIsTerminating: " + e.IsTerminating);
} //

private void button1_Click(object sender, RoutedEventArgs e) {
    throw new Exception("user exception thrown");
} //
Advertisements

Exiting Threads

You can use the Thread.Abort() method to kill a thread. This throws a ThreadAbort-Exception. The problem with this is that you do not know where exactly your program stops executing. It could be in the middle of an important calculation that makes a proper resource cleanup impossible. A more proper way would include a shared variable. By testing that variable you can exit your thread at predefined code positions.

private class parameters {
  //public double a;
  //public string s;
  public bool exitFlag = false;
}//

static private void myThread(object xParameters) {
  parameters p = xParameters as parameters;
  int i = 0;
  while (!p.exitFlag) {
    Console.WriteLine("thread loop number " + i++);
    Thread.Sleep(1000);
  }
  Console.WriteLine("good bye!");
  Thread.Sleep(2000);
} //

static void Main(string[] args) {
  Thread t = new Thread(new ParameterizedThreadStart(myThread));
  t.IsBackground = true;
  t.Name = "MyBackgroundThread";
  t.Priority = ThreadPriority.Normal;
  parameters p = new parameters();
  t.Start(p);

  Console.WriteLine("press return to exit the program");
  Console.ReadLine();

  p.exitFlag = true;
  t.Join();
} //

You can use a global static boolean to shut down a thread, but I think you will appreciate my solution using parameters as you can then reuse standard parameter interfaces and make your code more generic. You surely don’t want to deal with global variables when you have 100 threads running.

Exiting your application

In Windows.Forms applications you can use Application.Exit().  This method  terminates all message loops and closes all windows. You can eg. execute your cleanup code in the Form.OnClose events.
This method does not terminate your threads. If you do not deal with all your Foreground threads properly, then these threads  keep running. Therefore you must take measures to kill your threads.

The Environment.Exit() method is not part of Windows.Forms. It kills the process. Unsaved changes in forms may get lost. Again, you have to clean up properly and free resources.