Code example of multiple .NET AppDomains
From What is a开发者_StackOverflow .NET Application Domain?:
You can run several application domains in a single process with the same level of isolation that would exist in separate processes, but without incurring the additional overhead of making cross-process calls or switching between processes.
I would like to understand more about how/why one would actually use multiple AppDomains in their application. Can anyone provide an example with actual code snippets?
Reading the MSDN actually provides some good information.
http://msdn.microsoft.com/en-us/library/system.appdomain.aspx
--Dan
I have used this in the following context (don't have the code handy with me right now to post)
- Create a new AppDomain (e.g. appDomainX)
- Create a new instance of an object using this new domain
- The new object (lived in the new object) loads a bunch of assemblies
- Reflect on them to collect some metrics
- Get the result produced
- Unload appDomainX
The benefit of this is that you can unload assemblies loaded into the newly created AppDomain. If you are doing this on your main AppDomain over and over again loading more assemblies, your AppDomain will grow monstrously. Creating a separate AppDomain allows you to unload after each inspection which in turn unload all the assemblies loaded to that domain hence the main AppDomain remains clean.
I worked on a piece of (mostly) C++ software that allowed users to write scripts to automate the application using C#, or VB.NET. The application also had a few of its components written in C#. It used one AppDomain for the program components, and another to sandbox the scripts.
The original implementation of scripting created an AppDomain for each script, but that proved to be too slow and it prevented some useful script behaviors, so we went to one permanent AppDomain for the script engine.
You might want to use one to simulate the processing of IIS. You need a long running process that leaks memory. You can keep track of how many requests on AD has processed and one you reach a threshold, spin up a new one. When the old one has finished all processing unload it and let the CLR clean up some of the app junk.
Don't ask me how I know this. :)
You might also do this if you want to run code in different security contexts.
An extremely useful scenario for a .NET application to create multiple AppDomain
instances within its (single) process is to manage the scope of static variables across some large collection of conceptually-related object instances.
For example, consider a database app where 90% of the code manages a set of inter-related .NET objects that comprise the various tables, rows, and other view or data entities which all belong to the same top-level database. In writing the code for the database itself, it is nice to have each of the sub-instances in this object graph be self-sufficient, meaning each object alone carries (by containment) enough information to determine any/all context it needs to relate to the rest of the database, without demanding any external reference. This allows you to pass around any type of minor entity without worrying about what additional context it might internally require.
The price of this convenience is that every minor sub-object throughout the app then carries the context it requires as an internal field. If the app also needs to support multiple databases, for example to allow for comparing, importing, or exporting operations between databases (the other 10% of your code, say), then the context for every object must include information to distinguish, directly or indirectly, ultimately which database it belongs to.
This extra information can lead to memory bloat, especially in the more numerous low-level instances, and for a single, given "prevailing" database, much of this carried context will, by definition, be duplicative.
AppDomain
to the rescue... Instead, the database portion of your code can be associated with a distinct AppDomain
for each database. Since static variables scoped to their AppDomain
, you can associate the top-level information about the database with the AppDomain
, and every minor instance will inherently know which database it belongs to, either relative the AppDomain.CurrentDomain
static property, or by simply referencing static fields, properties, and methods you define, all without having any extra per-instance fields.
Note that the inter-database (that 10% part) code can only reference one database at a time this way. Any additional database(s) have to be referenced explicitly (in the traditional way) during such operations. For the main bulk of the code, however, this technique could eliminate potentially millions of object references deployed across all those context fields. And if you resist the idea of global singletons, note that AppDomain.CurrentDomain
exists in your .NET code already--so why not put it to good use!
精彩评论