I don't understand Application Domains
AppDomains best visualized as a very light weight process.
There can be N AppDomains per .Net Process but generally speaking there is only one. The real advantage of AppDomains is they provide an isolation boundary within your process. Objects can only talk to each other across an AppDomain boundary via remoting or serialization.
It's also possible to run 2 AppDomains at completely different security levels within a process. This can allow you to run your main application at Full Trust while running Untrusted Plugins at a much lower trust level.
It's hard to blanket say yes or no to whether or not a thread respects an AppDomain. It's possible for a single thread to be in N different AppDomains. Such a situation is possible if an object in one AppDomain makes a remote call to an object in another AppDomain. The thread will have to transition between the AppDomains in order to complete.
The disadvantage of AppDomains is mainly complexity. Remoting can take a little bit of time to get your head around and properly setting up an AppDomain can be a non-trivial process.
You may want to take a peek through the MSDN documentation on AppDomains. It's hard to find a succint tutorial that describes them because they have a variety of complex features. This provides a nice overview which if it doesn't answer your question directly will at least point you in the right place.
http://msdn.microsoft.com/en-us/library/cxk374d9.aspx
This document is no longer maintained please refer to this for the updated version: https://msdn.microsoft.com/en-us/library/2bh4z9hs(v=vs.110).aspx
JaredPar's answer is good, except he doesn't note the raison d'etre for AppDomains - which is that you can only UNLOAD an Assembly by unloading its AppDomain. If you are a long-running OS process, and you expect to have to load and then later unload assemblies for whatever reason then you need an AppDomain. The prototypical example here is ASP.NET, which loads app code assemblies on demand and then can unload them later, when the apps are no longer being actively used.
The cost you pay for the ability to unload is that independence - you need to communicate across the AppDomain boundary, Can't make a simple method call. You need to manage the AppDomain lifecycle. Etc.
If you just need to dynamically load Assemblies and don't think you'll need to unload them during the life of a single process then you probably don't need to run multiple AppDomains. A good example here might be a rich app that supports a plug-in model, where it sniffs out plug-in assemblies in a "etc" directory and loads 'em all up. However, if the plug-in model calls for unloading the plug-ins ... well.
There are outlyer scenarios. Like, suppose you want to load 2 different versions of an Assembly at the same time. You can run into pitfalls if you don't segregate them with AppDomains. But that will be fairly rare.
The core scenario that justifies the existence of AppDomains is the long running process that must be able to unload assemblies.
Of course, applications could rely on the OS process when you want to unload an assembly. In other words, you could have 3 or 4 cooperating processes running, each with its own set of Assemblies, and when you want to unload an assembly, just shut down the process that hosts that assembly. But the AppDomain offers a higher-perf mechanism to do that, without requiring process stop/start or cross-process comms, which is heavier still than the cross-AppDomain comms described previously. I mean it's still remoting but it is slower and more context switching.
Some things you can do with AppDomains:
- you can shut it down without endangering the stability of your program.
- You can load code and give this less privileges then your own process (e.g. your process runs fully trusted but you load code in a separate AppDomain that cannot even create a file on the disk.)
- You can handle unhandled exceptions of a AppDomain without having to crash your process.
- Etc.
Simply put, it's a security boundary and allmost a process boundary. As far as performance goes, multiple AppDomains within a process does not represent significant overhead. Launching a separate process instead of an AppDomain is far more costly.