Type Summary





Type Summary


   public sealed class AppDomain: MarshalByRefObject, IEvidenceFactory

       {

       // Properties

    MS CF public string BaseDirectory { get; }

    MS CF public static AppDomain CurrentDomain { get; }

    MS CF public string DynamicDirectory { get; }

    MS CF public Evidence Evidence { get; }

          public string FriendlyName { get; }

    MS CF public string RelativeSearchPath { get; }

    MS CF public AppDomainSetup SetupInformation { get; }

    MS CF public bool ShadowCopyFiles { get; }



       // Methods

    MS CF public void AppendPrivatePath(string path);

    MS CF public void ClearPrivatePath();

    MS CF public void ClearShadowCopyPath();

    MS CF public ObjectHandle CreateComInstanceFrom(string assemblyName,

                              string typeName);

MS CF 1.1 public ObjectHandle CreateComInstanceFrom(string assemblyFile,

                              string typeName, byte[] hashValue,

                              AssemblyHashAlgorithm hashAlgorithm);

       CF public static AppDomain CreateDomain(string friendlyName);

       MS public static AppDomain CreateDomain(string friendlyName,

                                  Evidence securityInfo);

    MS CF public static AppDomain CreateDomain(string friendlyName,

                                  Evidence securityInfo, AppDomainSetup info);

    MS CF public static AppDomain CreateDomain(string friendlyName,

                                  Evidence securityInfo,

                                  string appBasePath,

                                  string appRelativeSearchPath,

                                  bool shadowCopyFiles);

    MS CF public ObjectHandle CreateInstance(string assemblyName,

                              string typeName);

    MS CF public ObjectHandle CreateInstance(string assemblyName,

                              string typeName, bool ignoreCase,

                             BindingFlags bindingAttr, Binder binder,

                              object[] args, CultureInfo culture,

                             object[] activationAttributes,

                             Evidence  securityAttributes);

    MS CF public ObjectHandle CreateInstance(string assemblyName,

                              string typeName,      object[] activationAttributes);

    MS CF public object CreateInstanceAndUnwrap(string assemblyName,

                        string typeName);

    MS CF public object CreateInstanceAndUnwrap(string assemblyName,

                        string typeName, bool ignoreCase,

                         BindingFlags bindingAttr, Binder binder,

                         object[] args, CultureInfo culture,

                         object[] activationAttributes,

                         Evidence securityAttributes);

    MS CF public object CreateInstanceAndUnwrap(string assemblyName,

                        string typeName, object[] activationAttributes);

    MS CF public ObjectHandle CreateInstanceFrom(string assemblyFile,

                              string typeName);

    MS CF public ObjectHandle CreateInstanceFrom(string assemblyFile,

                              string typeName, bool ignoreCase,

                              BindingFlags bindingAttr, Binder binder,

                              object[] args, CultureInfo culture,

                              object[] activationAttributes,

                              Evidence securityAttributes);

    MS CF public ObjectHandle CreateInstanceFrom(string assemblyFile,

                              string typeName,

                              object[] activationAttributes);

    MS CF public object CreateInstanceFromAndUnwrap(string assemblyName,

                        string typeName);

    MS CF public object CreateInstanceFromAndUnwrap(string assemblyName,

                         string typeName, bool ignoreCase,

                         BindingFlags bindingAttr, Binder binder, object[] args,

                         CultureInfo culture, object[] activationAttributes,

                         Evidence securityAttributes);

    MS CF public object CreateInstanceFromAndUnwrap(string assemblyName,

                         string typeName, object[] activationAttributes);

    MS CF public AssemblyBuilder DefineDynamicAssembly(AssemblyName name,

                                 AssemblyBuilderAccess access);

    MS CF public AssemblyBuilder DefineDynamicAssembly( AssemblyName name,

                                 AssemblyBuilderAccess access,

                                 Evidence evidence);

    MS CF public AssemblyBuilder DefineDynamicAssembly(AssemblyName name,

                                 AssemblyBuilderAccess access,

                                 Evidence evidence,

                                 PermissionSet requiredPermissions,

                                 PermissionSet optionalPermissions,

                                 PermissionSet refusedPermissions);

    MS CF public AssemblyBuilder DefineDynamicAssembly(AssemblyName name,

                                 AssemblyBuilderAccess access,

                                 PermissionSet requiredPermissions,

                                 PermissionSet optionalPermissions,

                                 PermissionSet refusedPermissions);

    MS CF public AssemblyBuilder DefineDynamicAssembly(AssemblyName name,

                                 AssemblyBuilderAccess access, string dir);

    MS CF public AssemblyBuilder DefineDynamicAssembly(AssemblyName name,

                                 AssemblyBuilderAccess access, string dir,

                                 Evidence evidence);

    MS CF public AssemblyBuilder DefineDynamicAssembly(AssemblyName name,

                                 AssemblyBuilderAccess access, string dir,

                                 Evidence evidence,

                                 PermissionSet requiredPermissions,

                                 PermissionSet optionalPermissions,

                                 PermissionSet refusedPermissions);

    MS CF public AssemblyBuilder DefineDynamicAssembly(AssemblyName name,

                                 AssemblyBuilderAccess access, string dir,

                                 Evidence evidence,

                                 PermissionSet requiredPermissions,

                                 PermissionSet optionalPermissions,

                                 PermissionSet refusedPermissions,

                                 bool isSynchronized);

    MS CF public AssemblyBuilder DefineDynamicAssembly(AssemblyName name,

                                 AssemblyBuilderAccess access, string dir,

                                 PermissionSet requiredPermissions,

                                 PermissionSet optionalPermissions,

                                 PermissionSet refusedPermissions);

    MS CF public void DoCallBack(CrossAppDomainDelegate callBackDelegate);

       MS public int ExecuteAssembly(string assemblyFile);

    MS CF public int ExecuteAssembly(string assemblyFile,

                     Evidence assemblySecurity);

       MS public int ExecuteAssembly(string assemblyFile,

                     Evidence assemblySecurity, string[] args);

MS CF 1.1 public int ExecuteAssembly(string assemblyFile,

                     Evidence assemblySecurity,

                      string[] args, byte[] hashValue,

                      AssemblyHashAlgorithm hashAlgorithm);

    MS CF public Assembly[] GetAssemblies();

    MS CF public static int GetCurrentThreadId();

    MS CF public object GetData(string name);

    MS CF public Type GetType();

    MS CF public override object InitializeLifetimeService();

    MS CF public bool IsFinalizingForUnload();

    MS CF public Assembly Load(AssemblyName assemblyRef);

    MS CF public Assembly Load(AssemblyName assemblyRef,

                          Evidence assemblySecurity);

    MS CF public Assembly Load(byte[] rawAssembly);

    MS CF public Assembly Load(byte[] rawAssembly, byte[] rawSymbolStore);

    MS CF public Assembly Load(byte[] rawAssembly, byte[] rawSymbolStore,

                          Evidence securityEvidence);

    MS CF public Assembly Load(string assemblyString);

    MS CF public Assembly Load(string assemblyString,

                          Evidence assemblySecurity);

    MS CF public void SetAppDomainPolicy(PolicyLevel domainPolicy);

    MS CF public void SetCachePath(string path);

    MS CF public void SetData(string name, object data);

    MS CF public void SetDynamicBase(string path);

    MS CF public void SetPrincipalPolicy(PrincipalPolicy policy);

    MS CF public void SetShadowCopyFiles();

    MS CF public void SetShadowCopyPath(string path);

    MS CF public void SetThreadPrincipal(IPrincipal principal);

       CF public override string ToString();

       CF public static void Unload(AppDomain domain);



       // Events

       CF public event AssemblyLoadEventHandler AssemblyLoad;

    MS CF public event ResolveEventHandler AssemblyResolve;

       CF public event EventHandler DomainUnload;

    MS CF public event EventHandler ProcessExit;

    MS CF public event ResolveEventHandler ResourceResolve;

    MS CF public event ResolveEventHandler TypeResolve;

       CF public event UnhandledExceptionEventHandler UnhandledException;

       }


BA We introduced Application Domains as a lightweight process mechanism. Because managed code can be verifiably type safe (memory safe) we did not need the heavyweight address space barrier that processes provide. This savings works out well most of the time. However, when using interop with unmanaged code it does cause some problems when type safety is violated. One notable example of this is the loader-lock and AppDomain marshaling problem that C++ was susceptible to. We fixed this problem in a service pack of v1.1.

JM The ECMA standard AppDomain only inherits from MarshalByRefObject. IEvidenceFactory and _AppDomain are Microsoft implementation–specific "extensions" to support functionality (e.g., security) added by Microsoft.

JM You can notice quite easily that the ECMA standard AppDomain contains minimal functionality as compared with the Microsoft implementation. Basically, the ECMA standard AppDomain type only provides mechanisms to create and unload application domains. Reasons for this include the minimum security sets for the ECMA standard, Microsoft-specific functionality, as well as lack of type availability within the standard.

JM Partition I of the ECMA standards describes, in relatively minute detail, the concept of application domains. Only single application domain support is required for a conformant CLI implementation, although the usefulness of application domains really stems from the isolation and remoting capabilities they provide when multiple application domain support is available.

BG Originally, we added AppDomains just to support the notion of unloading assemblies. Unloading code is somewhat tricky, especially if you don't want to pay some penalties every time you call a virtual method. AppDomains were a rather heavyweight mechanism, but they solved this goal. They also greatly complicated the CLR (Common Language Runtime) internally, especially when we tried to add features like generics in version 2.

However, the concept of an application domain as a unit of state isolation within the process has proved invaluable for our reliability story in version 2. In ASP.NET, the server was very successful with process recycling, i.e., restarting the server's worker processes when they ran out of memory or hit some other potentially critical failure. Here, all state in the process was thrown away when a critical resource failure occurred. We're leveraging the same idea of AppDomain recycling to achieve our reliability goals for SQL Server and other similar managed hosts, where you don't want to recycle the server process. AppDomain recycling is the key to being able to kill errant parts of an application, then throw away potentially corrupt state. In a transacted environment like a database, you can (generally) safely throw away all state within the AppDomain if you detect that any shared state within that AppDomain has been corrupted. (By shared state, I mean any state accessible from a static variable or some other cross-thread sharing mechanism.)

We have a pretty good heuristic for detecting corruption to shared state. Assuming there are no bugs in the code you're running, the only time you'll see shared state corruption is when an asynchronous exception (such as an OutOfMemoryException, ThreadAbortException, or StackOverflowException) occurs within a method that holds a lock. The idea here is that all synchronous exceptions should be handled by the application and the application generally shouldn't be written to deal with asynchronous exceptions. Then the natural way to edit shared state in a multi-threaded system is to take a lock.

For SQL Server, we have a system for escalating failures based on the above notions. If we get an OutOfMemoryException on a thread that isn't editing shared state (i.e., doesn't hold any locks), then we simply abort that thread. If the thread did hold a lock, then we pessimistically assume that at least some amount of shared state within that application domain is corrupt, so we escalate this failure to an AppDomain unload. This way we can tear down any threads that may potentially generate incorrect results. In this way, we escalate critical resource failures to AppDomain unloads.

There are a lot more subtleties to how we have implemented our escalation policy and the extremely corrupting nature of asynchronous exceptions, which led to the design of new reliability primitives like constrained execution regions, critical finalization, and SafeHandle. An example would be critical finalization. If a critical resource failure occurs when running a finalizer during an AppDomain unload (such as running out of memory to JIT compile the method), then we've introduced the notion of normal AppDomain unloads and rude AppDomain unloads. During a rude AppDomain unload, we won't run arbitrary user finalizers, but only trusted finalizers that have been eagerly prepared. This is known as critical finalization, and was designed to support SafeHandle so that a library developer has a chance to free OS resources even when we're escalating a critical failure.

Anyone who is building a host for running other managed code in-process with strict reliability concerns should research this area in great detail. This same escalation policy is accessible via our unmanaged hosting API for the CLR, and a carefully written all-managed application can probably achieve the same level of reliability with careful use of AppDomain's Unload method in conjunction with some other reliability primitives.

AN AppDomain is one of the few classes in the .NET Framework that is commonly used via COM Interop (often for CLR hosting scenarios), so we made a point of exposing most of its functionality via an interface called _AppDomain. Exposing a real managed interface to COM consumers is much better than taking advantage of our regrettable "class interface" functionality, since we avoid a host of versioning problems by being in complete control of what gets exposed. The unfortunate thing about _AppDomain (besides the non-standard name, which I know drives folks like Brad crazy) is that the overloaded members are still just as clunky to use from COM. For example, the Load overloads are exposed as Load, Load_2, Load_3, and so on. But because of the versioning benefits, expect more of our COM-visible classes in the .NET Framework to start implementing real interfaces like _AppDomain and stop exposing class interfaces in the future.



     Python   SQL   Java   php   Perl 
     game development   web development   internet   *nix   graphics   hardware 
     telecommunications   C++ 
     Flash   Active Directory   Windows