I need to have an event fired whenever any AppDomain unloads - including the default one of the process. The problem with AppDomain.DomainUnload is that it only fires for non-default AppDomains. Furthermore, AppDomain.ProcessExit has limited execution time, which I cannot rely on.
Any suggestions as to how I can achieve this would be greatly appreciated!
(Alternatively, having an event fired when a background thread (Thread.IsBackground == True) works too.)
Why do you not put your code in the end of Main?
As for an event:
No there is no event which will get executed when the application domain is unloaded. If you are a library developer you add a destructor to your entry class. But beware that everything might not be collected properly. Read this answer: https://stackoverflow.com/a/2735431/70386
http://msdn.microsoft.com/en-us/library/system.appdomain.domainunload%28v=VS.90%29.aspx ..but again this is called before the domain is unloaded.
Taken from http://msdn.microsoft.com/en-us/library/system.appdomain.unload.aspx
In the .NET Framework version 2.0 there is a thread dedicated to unloading application domains. This improves reliability, especially when the .NET Framework is hosted. When a thread calls Unload, the target domain is marked for unloading. The dedicated thread attempts to unload the domain, and all threads in the domain are aborted. If a thread does not abort, for example because it is executing unmanaged code, or because it is executing a finally block, then after a period of time a CannotUnloadAppDomainException is thrown in the thread that originally called Unload. If the thread that could not be aborted eventually ends, the target domain is not unloaded. Thus, in the .NET Framework version 2.0 domain is not guaranteed to unload, because it might not be possible to terminate executing threads.
What about using a wrapper/launcher around your main application? That AppDomain could notice when its child ends (via blocking, polling or callback) and could perform whatever additional operations are needed.
Likewise, if main() consists of starting a single thread which does all the important stuff, then main() could also perform whatever additional work is needed.
Perhaps it would help if you could explain what you need to do in response to each AppDomain termination? It could be that what you are asking to do just isn't appropriate at the AppDomain level.
If your goal here is to cleanly dispose of objects that are used by some background threads, then my suggestion would be:
When you want your want to exit the application, signal to the background threads that they should clean up and stop.
From the main thread, use Thread.Join
to wait for all the background threads to finish and exit.