using System;
using System.Threading;
using System.Drawing;
using System.Windows.Forms;

class ExceptionForm : Form {
   
   public ExceptionForm() {

      String[] buttonStrings = {
         "Throw From This Button's Event Handler",
         "Close Window and Throw After the Fact",
         "Create a Thread and Throw From It",
         "Throw From a Thread-pool Thread",
         "Throw From a Finalizer Method"         
         };      

      for (Int32 index = 0; index < buttonStrings.Length; index++) {
         Button button = new Button();
         button.Text = buttonStrings[index];
         button.Size = new Size(224, 24);
         button.Location = new Point(8, 11 + index * 32);
         button.Click += new EventHandler(OnButtonClick);
         Controls.Add(button);
      }

      ClientSize = new Size(240, 174);
      Text = "Exception Form";
   }

   private void OnButtonClick(Object sender, EventArgs args) {

      switch (((Button)sender).Text) {
      case "Throw From This Button's Event Handler":
         throw new InvalidOperationException();

      case "Close Window and Throw After the Fact":
         App.shouldThrowOnExit = true;
         Close();
         break;

      case "Create a Thread and Throw From It":
         Thread t = new Thread(new ThreadStart(ThreadMethod));
         t.Start();
         break;

      case "Throw From a Thread-pool Thread":
         ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolMethod));
         break;

      case "Throw From a Finalizer Method":
         CreateObjectThatThrowsOnFinalize();
         GC.Collect();
         GC.WaitForPendingFinalizers();
         break;
      }
   }

   void ThreadMethod() {
      throw new InvalidOperationException();
   }

   void ThreadPoolMethod(Object param) {
      throw new InvalidOperationException();
   }

   void CreateObjectThatThrowsOnFinalize() {
      new ThrowsOnFinalize();
   }

   class ThrowsOnFinalize {
      ~ThrowsOnFinalize() {
         throw new InvalidOperationException();
      }
   }
}

class App {

   internal static Boolean shouldThrowOnExit = false;

   public static void Main() {
      Application.Run(new ExceptionForm());
      if (shouldThrowOnExit) 
         throw new InvalidOperationException();
   }
}
