Unload event for the default AppDomain?

2019-06-03 11:08发布

问题:

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.)

回答1:

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



回答2:

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.



回答3:

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.



回答4:

If your goal here is to cleanly dispose of objects that are used by some background threads, then my suggestion would be:

  1. When you want your want to exit the application, signal to the background threads that they should clean up and stop.

  2. From the main thread, use Thread.Join to wait for all the background threads to finish and exit.