We have an application which, as one of its requirements, will take arbitrary 3rd party plugins, load them, and run their UI alongside our home-grown application. We've been loading these 3rd party plugins into their own AppDomains for isolation purposes, and everything works ok.
Until one of the plugins crashes out with an unhandled exception. In this circumstance, the entire application goes down, even though all that is really affected is one of our 'extra' tool windows.
We'd like, ideally, some way to handle the "unhandled" exception, unload the damaged AppDomain, and then just reload it fresh. The problem is that we can't find a mechanism in the event handler for the unhandled exception whereby we can flag the exception as being 'handled'. Further, since the plugins have their own UI components with their own set of interactions with the user, it would be extremely difficult to "wrap" our interactions with the plugins in try/catch/finally blocks.
Are there any frameworks/programming libraries/patterns that lend themselves to solving this problem? We can do plugin stuff fine; what we need help with is keeping the application alive when code in a different AppDomain fails unexpectedly.
You can use the
System.Addin
framework (sometimes known asMAF
), which is a bit of a hassle to set up correctly, but which was designed to provide isolation (crash protection).System.Addin
is based on remoting. With this framework you can let plugins run with limited permissions, in the same process, or in another app-domain, or even in another process.If you need total crash protection you may need to use the process separation option. It may come at the cost of performance though.
You can use this code to load an addin in a different app domain:
If you want to load the addin into another process, for complete isolation:
This blog gives a good description of setting this up.
It is possible to combine
System.Addin
with MEF, these are complimentary toolkits, see this article.Note that the System.Addin model may provide crash protection, you will still need to deal with slowdowns or deadlocks in the addin code. Asynchronous usage will help here.
I assume that you've already checked the documentation thourougly but if not the following page
http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx
does provide a lot of information on how the unhandled exceptions work. It also mentions several attributes that allow to fine tune the behavior.
Unfortunately I cannot give you any tips on your specific situation as I haven't used separate AppDomains in this way. What I can say is that from my experience with the UnandledException event the IsTerminating flag is rarely true and we are almost always able to recover from an unhandled exception.
I would go with MEF
http://msdn.microsoft.com/en-us/library/dd460648.aspx
I do not think this is possible. My understanding is that even if you handle the AppDomain.UnhandledException event, the application will still terminate. The best you can do is handle the exception, log what you can, save what state that you can, and terminate gracefully.
Sounds like you'd want something similar to OSGi for Java -- Is MEF OSGi for .NET? looks like it might fit the bill.