简体   繁体   中英

How to handle exceptions thrown from another AppDomain?

I have a WPF bootstrapper application: it loads my application UI from a separate assembly into another AppDomain then shows the main window. So the application UI runs from this subdomain.

The question : How to handle exceptions in the main domain thrown from the subdomain?

Why? Because my goal is to implement an application updater: when the client realizes that there is a new version is available it would throw some SystemException with a specific message.

I want the host domain to handle this specific exception: unload the subdomain, download the latest assembly version from the internet and recreate the subdomain by reloading the most up-to-date DLLs.

The problem : It seem to me that an unhandled exception in any AppDomain causes the whole thread to terminate. I found some blog post stating that one should turn on the legacyUnhandledExceptionPolicy to switch back to the .NET 1.0/1.1 legacy mode exception handling, but I'm not sure that I want to use this legacy stuff in my application.

Is there any other way to properly handle exception in other AppDomains?

The general approach to handle custom exception 'E' caused in AppDomain-A is to have this exception defined in an assembly that is registered in GAC. So, AppDomain-A references this common assembly and AppDomain-B (observer) references this assembly.

This is because the Exception class is [Serializable] and will be passed by value over the domain boundary. Once you get the blob through the boundary, CLR will try to deserialize it. So CLR must be able to find appropriate type for deserialization. So, deserialization will lookup for the exception type according to standard rule.

There could be of course another solutions with type resolution behavior changes diving deep serialization/deserialization mechanisms.

In case if you want to learn more, just read Jeffry's book chapter about the serialization mechanisms and versioning.

If the appdomain is running on another thread use the AppDomain.UnhandledException event handler to handle uncaught exceptions in your new appdomain

newAppDomain.UnhandledException += new UnhandledExceptionEventHandler(ErrorHandler);

public void ErrorHandler(object sender, UnhandledExceptionEventArgs args) 
{
    Exception e = (Exception) args.ExceptionObject;
    // handle here
}

A different approach is to unload the appdomain using AppDomain.Unload, the assembly in the appdomain should handle AppDomain.DomainUnload event to close down gracefully. You can then spawn a new appdomain and start again.

This is assuming you are running the new app domain on a seperate thread, otherwise you will need to handle the exception around the calling code from the parent, becuase an unhandled exception on the main thread will abort the process.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM