user65199
user65199

Reputation:

How to detect when application terminates?

This is a follow up to my initial question and I would like to present my findings and ask for corrections, ideas and insights. My findings (or rather interpretations) come from people's answers to my previous question, reading MSDN .NET 3.5 documentation and debugging .NET 3.5 code. I hope this will be of value to someone who was wondering like me how to detect when an application terminates.

Events:

Order of events:

WPF application: graceful exit

  1. System.Windows.Application.Exit
  2. System.AppDomain.CurrentDomain.ProcessExit
  3. Finalizers

WPF application: unhandled exception

  1. System.AppDomain.CurrentDomain.UnhandledException

MbUnit running inside TestDriven.NET: passed test (graceful exit)

  1. System.AppDomain.CurrentDomain.DomainUnload
  2. Finalizers

MbUnit running inside TestDriven.NET: failed test (unhandled exceptions are handled by MbUnit)

  1. AppDomain.CurrentDomain.DomainUnload
  2. Finalizers

Questions:

Upvotes: 64

Views: 18967

Answers (5)

Daj Shung
Daj Shung

Reputation: 47

Just add a new event on your main form:

private void frmMain_Load(object sender, EventArgs e)
{
  Application.ApplicationExit += new EventHandler(this.WhenItStopsDoThis);
}

private void WhenItStopsDoThis(object sender, EventArgs e)
{
  //Program ended. Do something here.
}

Upvotes: -1

Eyvind
Eyvind

Reputation: 5261

You write:

System.AppDomain.CurrentDomain.UnhandledException: (if handled in default AppDomain:) raised for any unhandled exception in any thread, no matter what AppDomain the thread started in. This means, this can be used as the catch-all for all unhandled exceptions.

I do not think that this is correct. Try the following code:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace AppDomainTestingUnhandledException
{
    class Program
    {
        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException +=
                (sender, eventArgs) => Console.WriteLine("Something went wrong! " + args);

            var ad = AppDomain.CreateDomain("Test");

            var service =
                (RunInAnotherDomain)
                ad.CreateInstanceAndUnwrap(
                    typeof(RunInAnotherDomain).Assembly.FullName, typeof(RunInAnotherDomain).FullName);

            try
            {
                service.Start();
            }
            catch (Exception e)
            {
                Console.WriteLine("Crash: " + e.Message);
            }
            finally
            {
                AppDomain.Unload(ad);
            }
        }
    }

    class RunInAnotherDomain : MarshalByRefObject
    {
        public void Start()
        {
            Task.Run(
                () =>
                    {
                        Thread.Sleep(1000);
                        Console.WriteLine("Uh oh!");
                        throw new Exception("Oh no!");
                    });

            while (true)
            {
                Console.WriteLine("Still running!");
                Thread.Sleep(300);
            }
        }
    }
}

As far as I can tell, the UnhandledException handler is never called, and the thread will just silently crash (or nag at you if you run it in the debugger).

Upvotes: 1

FooBarTheLittle
FooBarTheLittle

Reputation: 459

When Dispatcher.BeginInvokeShutdown() is called, Application.Exit will not be called.

Upvotes: 2

unknown
unknown

Reputation:

  1. The default timeout for a finalizer's execution is 2 seconds.

Upvotes: 1

Ray
Ray

Reputation: 46585

Prompted by ssg31415926's question/answer (this question is a bit reversed), there's also Application.SessionEnding which is called when the when the user logs off or shuts down. It is called before the Exit event.

Upvotes: 7

Related Questions