Section Ii: AppDomain

Source: Internet
Author: User
Tags configuration settings first string mscorlib switches
<span id="Label3"></p><p><p>When the CLR COM server is initialized, an AppDomain is Created. An AppDomain is a logical container for a set of Assemblies. The first AppDomain created when the CLR initializes is called the default appdomain, and the default AppDomain can be revoked only when the WINDONWS process Terminates.</p></p><p><p>In addition to the default appdomain, a host that is using an unmanaged COM interface method or a managed type method can also instruct the CLR to create additional appdomain,appdomain that the only effect is process Isolation. The following summarizes the specific functions of the Appdomain.</p></p><p><p><strong>1.1.</strong> The code in <strong>one AppDomain</strong> <strong>creates an object that cannot be</strong> <strong>accessed directly by code in another Appdomain. </strong></p></p><p><p>After the code in an AppDomain creates an object, the object is "owned" by the Appdomain. In other words, its lifetime cannot be longer than the AppDomain in which the code that created it is Located. Code in one AppDomain to access objects in another appdomain, you can only use the semantics of Marshal by reference or Marshal by Value. This reinforces a clear separation and boundary, because the code in one AppDomain does not have a direct reference to the object created by the code in another Appdomain. This isolation makes it easy for the AppDomain to unload from one process without affecting the code that other applications are running.</p></p><p><p>2.<strong> AppDomain</strong> <strong>can unload</strong> the CLR does not support the ability to unload an assembly from the AppDomain. however, you can tell the CLR to unload an appdomain, thereby unloading all the assemblies currently contained within that Appdomain.</p></p><p><p>3. <strong>AppDomain</strong> <strong>can protect</strong> the AppDomain individually after it is created, a permission set is applied that determines the maximum permissions granted to assemblies running in this Appdomain. It is because of these permissions that, when the host loads some code, it guarantees that the code will not be destroyed by some of the important data interfaces used by the host Itself.</p></p><p><p>4<strong>. The AppDomain</strong> <strong>can be implemented separately configuration </strong>AppDomain is associated with a set of configuration settings after it is Created. These configurations primarily affect how the CLR loads assemblies in the Appdomain. These settings involve search paths, version binding redirects, Shadow assignments, and loader optimizations.</p></p><p><p>Important: One of the great features of Windows is to have each utility run in its own process address space. This ensures that one Application's code cannot access code or data used by another Application. Process isolation protects against security breaches, data corruption, and other unpredictable behavior, ensuring the robustness of Windows systems and the applications running on Them. unfortunately, the cost of creating a process in Windows is Significant. The Win CreateProcess function is slow, and the window system requires a lot of memory to virtual the address space of a process.</p></p><p><p>however, If the application is completely composed of managed code (the security of the code can be verified) and the code does not call unmanaged code, It is not a problem to run multiple managed code in a window process. The AppDomain provides the isolation required to protect, configure, and terminate each of these Applications.</p></p><p><p>Demonstrates a Windows process in which a CLR Com server is Running. This CLR currently manages these two appdomain. Each AppDomain has its own loader heap, and each loader heap records which types have been accessed since the AppDomain was Created. Each type object in the loader heap has a method table, and each record entry in the method table points to the jit-compiled local Code.</p></p><p><p></p></p><p><p></p></p><p><p></p></p><p><p></p></p><p><p>In addition, each AppDomain loads some Assemblies. The AppDomain #1 (the default Appdomain) has three assemblies: Myapp.exe,typelib.dll and System.dll. Appdomain#2 has two assemblies: Wintellect.dll and System.dll.</p></p><p><p>, the System.dll assembly is loaded into two appdomain. If all two AppDomain uses a type from System.dll, then in the loader heap of these two appdomain, a type object is assigned to the same type, and the memory of the type object is not shared by two Appdomain. In addition, when code in an AppDomain calls a method of a type definition, the IL code of the method is jit-compiled, and the generated native code is associated with each appdomain, and the code of the method is not shared by all the AppDomain that called it.</p></p><p><p>It is a waste of course to not share the memory or local code of the type Object. however, the whole purpose of the AppDomain is isolation; the CLR requires that an AppDomain be unloaded and all its resources released without adversely affecting the other Appdomain. This can be ensured by assigning the data structure of the CLR. In addition, you can guarantee that a type used by multiple AppDomain has a set of static fields in each Appdomain.</p></p><p><p>Some assemblies are intended to be used by more than one appdomain. The most typical example is MSCorLib.dll. The assembly contains System.object,system.int32 and all other types that are inseparable from. NET Farmework. When the CLR initializes, the assembly is loaded automatically, and all the AppDomain shares the types in that assembly. To reduce resource consumption, the MsCorLib.dll assembly is loaded in an "appdomain-neutral" manner. That is, for assemblies that are loaded in an "appdomain-neutral" manner, the CLR maintains a special loader heap for Them. All the types of objects in the loader heap, and all local code generated for the methods that are defined for those types, are shared by all the AppDomain in the Process. unfortunately, the benefits of sharing these resources are not without cost. The price is that all assemblies loaded in an "appdomain-neutral" manner can never be uninstalled. The only way to reclaim the resources they occupy is to terminate the Windows Process and allow window to reclaim Resources.</p></p><p><p><strong>across the AppDomain</strong> <strong>Boundary Access Object</strong></p></p><p><p>The code in one AppDomain can communicate with types and objects in another appdomain. however, These types and objects are only allowed to be accessed through well-defined mechanisms. The following Ch22-1-appdomains sample program demonstrates how to create a new appdomain, load an assembly in it, and then construct an instance of the type defined by that assembly. The code demonstrates different behavior when constructing the following three types: a type that is marshaled by reference, a type that is marshaled by value, and a type that cannot be marshaled at All. The code also demonstrates the behavior of these marshaled objects when they create their AppDomain Uninstallation. The code for the Ch22-1appdomains sample program is actually very small, but I've added a lot of comments. After the code listing, i'll parse the code and parse what the CLR Does.</p></p><pre class="brush:csharp;gutter:true;">namespace Ch22_1_appdomains{class program {static void Main (string[] Args) {//marshallin G (); appDomainResourceMonitoring (); } private static void marshalling () {//gets a reference to the AppDomain (the calling thread is currently executing in the Appdomain) APPD Omain Adcallingthreaddomain = Thread.getdomain (); Gets the friendly string name of this AppDomain and displays it as String callingdomainname = adcallingthreaddomain.friendlyname; Console.WriteLine ("Default AppDomain ' s friendly name={0}", callingdomainname); Gets the assembly that shows the main method contained in our appdomain, string exeassembly = assembly.getentryassembly (). FullName; Console.WriteLine ("Main assembly={0}", exeassembly); Define a local variable to reference an appdomain appdomain ad2 = null; Demo1: use Marshal-by-reference to communicate across AppDomain ..... Console.WriteLine ("{0} Demo #1", environment.newline); Create a new AppDomain (security and configuration matches the current Appdomain) ad2 = AppdoMain. CreateDomain ("AD #2", null, null); Marshalbyreftype MBRT = null; Load our assembly into the appdomain, construct an object, and marshal him back to our AppDomain (the actual reference to an agent) MBRT = (marshalbyreftype) ad2. Createinstanceandunwrap (exeassembly, "ch22_1_appdomains.marshalbyreftype"); The CLR lied on the type Console.WriteLine ("type={0}", mbrt. GetType ()); The proof is that the reference to a proxy object Console.WriteLine ("type={0}", remotingservices.istransparentproxy (mbrt)); Mbrt. SomeMethod (); Uninstall the new AppDomain appdomain.unload (ad2); Try {mbrt. SomeMethod (); Console.WriteLine ("successful call."); } catch (appdomainunloadedexception) {console.writeline ("Failed call."); }//demo 2: use Marshal-by-value for cross-appdomain communication .... Console.WriteLine ("{0} Demo #2", environment.newline); Create a new AppDomain (security and matching with current Appdomain) ad2 = APPDOmain. CreateDomain ("AD #2", null, null); MBRT = (marshalbyreftype) ad2. Createinstanceandunwrap (exeassembly, "ch22_1_appdomains.marshalbyreftype"); Marshalbyvaltype MBVT = Mbrt. Methodwithreturn (); proves that what we get is not a reference to a proxy object Console.WriteLine ("is proxy={0}", remotingservices.istransparentproxy (mbvt)); Console.WriteLine ("returned Object created" + Mbvt. ToString ()); Uninstall AppDomain appdomain.unload (ad2); Try {console.writeline ("returned object created" + Mbvt. ToString ()); Console.WriteLine ("sucessful call"); } catch (appdomainunloadedexception) {console.writeline ("Failed call."); } Console.WriteLine ("{0} Demo #3", environment.newline); Ad2 = Appdomain.createdomain ("AD #2", null, null); MBRT = (marshalbyreftype) ad2. Createinstanceandunwrap (exeassembly, "ch22_1_appdomains.marshalbYreftype "); The Object's method returns an object that is not marshaled, and throws an exception nonmarshalabletype NMT = Mbrt. Methodargandreturn (callingdomainname); } private static void appDomainResourceMonitoring () {using (new appdomainmonitordelta (null)) {var list = new List<object> (); For (Int32 x = 0; x < n, + +) List. ADD (new byte[10000]); For (Int32 x = 0; x < n × x + +) new byte[1000]. GetType (); Int64 stop = Environment.tickcount + 5000; While (environment.tickcount < stop); }}}//the instance can be marshaled across the Appdomain's boundary "by reference" public sealed class Marshalbyreftype:marshalbyrefobject {pu Blic Marshalbyreftype () {console.writeline (' {0} actor running in {1} ', This. GetType (). ToString (), Thread.getdomain (). friendlyname); } public void SomeMethod () {console.writeline ("executing in" + thread.getdoMain (). friendlyname); } public marshalbyvaltype Methodwithreturn () {console.writeline ("executing in" + thread.getdoma In (). friendlyname); Marshalbyvaltype t = new Marshalbyvaltype (); Return t; } public nonmarshalabletype Methodargandreturn (String Callingdomainname) {console.writeline ("Cal Ling from ' {0} ' to ' {1} ', callingdomainname, Thread.getdomain (). friendlyname); Nonmarshalabletype t = new Nonmarshalabletype (); Return t; }}//instances of this type can "marshal by value" across the Appdomain's boundary [Serializable] public sealed class Marshalbyvaltype:object {pri vate datetime m_creatingtime = Datetime.now;//note that datetime is a public marshalbyvaltype that can be serialized () {Conso Le. WriteLine ("{0} actor running in {1},created to {2:d}", This. GetType (). ToString (), Thread.getdomain (). friendlyname, m_creatingtime); } public override String ToString () {return m_creatingtime.tolongdatestring (); }}//instances of this class cannot be marshaled to the AppDomain boundary for public sealed class Nonmarshalabletype:object {public nonmarshalablety PE () {console.writeline ("executing in" + thread.getdomain (). friendlyname); }} sealed class appdomainmonitordelta:idisposable {private AppDomain m_appdomain; Private TimeSpan m_thisadcpu; Private Int64 m_thisadmemoryinuse; Private Int64 m_thisadmemoryallocated; Static Appdomainmonitordelta () {//ok to open AppDomain monitoring appdomain.monitoringisenabled = true; } public Appdomainmonitordelta (AppDomain ad) {m_appdomain = ad?? appdomain.currentdomain; M_THISADCPU = m_appdomain.monitoringtotalprocessortime; Returns the number of bytes that are being used by all the appDomain controlled by the current CLR instance m_thisadmemoryinuse = m_appdomain.monitoringsurvivedmemorysize; Returns the number of bytes allocated by a specific appDomain m_thisadmemoryallocated = m_appdomain.monitoringtotalallocatedmemorysize; public void Dispose () {GC. Collect (); Console.WriteLine ("friendlyname={0},cpu={1}ms", m_appdomain.friendlyname, (m_appdomain.monitoringtotalproce Ssortime-m_thisadcpu). totalmilliseconds); Console.WriteLine ("allocated {0:n0} bytes of which {1:n0} survived GCs", m_appdomain.monitoringtotalallocat edmemorysize-m_thisadmemoryallocated, m_appdomain.monitoringsurvivedmemorysize-m_thisadmemoryinuse); } }}</pre><p><p>  </p></p><p><p></p></p><p><p></p></p><p><p></p></p><p><p></p></p><p><p>We will now explain the above example: in the marshalling method, you first get a reference to an AppDomain object, and the current call line is impersonating is executed in this appdomain. In windows, threads are always created in the context of a process, and the entire lifetime of the thread is within the lifetime of the Process. But there is no one-to-one relationship between the thread and the Appdomain. The AppDomain is a CLR feature: windows has no knowledge of the Appdomain. Because multiple AppDomain can be in one Windows process, threads can execute code in one AppDomain and then execute code in another Appdomain. From the CLR perspective, the thread executes only one AppDomain at a time, and the thread can invoke the static method of thread GetDomain to ask the CLR if it is executing in that appdomain, Threads can also query the AppDomain for static read-only properties CurrentDomain to get the same information.</p></p><p><p>After the AppDomain is created, it can be given a friendly name, this friendly name is just a string and we can use it to identify an appdomain. Friendly names are generally useful during debugging. Because the CLR creates the default AppDomain before any of our code runs, the CLR uses the executable File's filename as the default appdomain-friendly Name. In the marshalling method, you use the Read-only property of the AppDomain friendlyname to query the default Appdomain's friendly Name.</p></p><p><p>next, the Marshalling method queries the strong-named identity of the assembly that is loaded in the default appdomain, which defines the entry method Main. This assembly defines several types: program, marshalbyreftype, marshalbyvaltype, nonmarshalabletype.</p></p><p><p>Demo 1: Cross-appdomain communication with "marshal by reference"</p></p><p><p>In demo 1, I call the Appdomain.createdomain () method, which tells the CLR to create a new AppDomain in the same Windows Process. The AppDomain type actually provides several overloaded versions of the CreateDomain Method. You can study it carefully and choose one of the most appropriate versions when you create a new appdomain. This example uses a CreateDomain version that accepts three Parameters.</p></p> <ol> <ol> <li>A string that identifies the friendly name that you want to assign to the new Appdomain. In this case, the AD #2 is Passed.</li> <li>A System.Security.Policy.Evidence that identifies the evidence that the CLR uses to calculate the set of permissions for the Appdomain. This example provides a null for this parameter, allowing the new AppDomain to inherit the permission set from the AppDomain that created it. In general, if you want to create a security boundary around the code in the appdomain, you can construct a System.Security.PermissionSet object that adds the desired permission object (an instance of the type that implements the IPermission interface). The last obtained PermissionSet object reference is passed to the overloaded version of CreateDomain that accepts a permissionset.</li> <li>A system.appdomainsetup that identifies the configuration settings that the CLR uses for the new Appdomain.</li> </ol> </ol><p><p>again, This example passes a null for the parameter so that the new AppDomain inherits the configuration settings from the AppDomain that created it. If you want a new AppDomain to have a special configuration, you can construct a AppDomainSetup object, set its various properties to the value you want, and then pass the resulting AppDomainSetup object reference to the CreateDomain method.</p></p><p><p>internally, The CreateDomain method creates a new AppDomain that will be given the specified friendly name, security, and configuration settings. The new AppDomain has its own loader heap, and this heap is currently empty because there are no assemblies loaded into the new appdomain, and when the AppDomain is created, The CLR does not create any threads in this appdomain: the AppDomain also has no code to run unless you display code that lets a thread invoke the Appdomain.</p></p><p><p>now, in order to create an instance of a type in the new appdomain, you must first load an assembly into the new AppDomain and then construct an instance of the type defined in the Assembly. This is what createinstanceandunwrap the common instance method of the AppDomain Does. When I call this createinstanceandunwrap method, I pass two string arguments, the first string identifies the assembly that you want to load in the new appdomain, and the second parameter identifies the name of the type whose instance you want to Construct. internally, the Createinstanceandunwrap method causes the calling thread to go from the current AppDomain to the new Appdomain. The thread now loads the specified assembly into the new appdomain, and scans the assembly for the type definition metadata table, looking for the development type. After the type is found, the thread calls Marshalbyreftype's parameterless Constructor. Now the thread returns to the default appdomain, allowing Createinstanceandunwrap to return a reference to the new Marshalbyreftype Object.</p></p><p><p>All this sounds good, but there is one problem: the CLR does not allow a variable (root) in one AppDomain to reference an object created in another Appdomain. If Createinstanceandunwrap only returns object references directly, the isolation provided by the AppDomain is broken, and isolation is the whole purpose of the appdomain! therefore, before Createinstanceandunwrap returns an object reference, It also performs some additional logic.</p></p><p><p>The Marshalbyreftype type is derived from a very special base class Marshalbyrefobject. When Createinstanceandunwrap discovers that the base class of an object it marshals derives from marshalbyrefobject, the CLR marshals the object by reference across the AppDomain boundary. Here's a lawsuit. by reference an object is marshaled from one AppDomain (the source appdomain, where the object is actually created) to another AppDomain (the target appdomain, where Createinstanceandunwrap is Called) The specific meaning.</p></p><p><p>When the source AppDomain wants to send or return an object reference to the target appdomain, the CLR defines a proxy type in the loader heap of the target Appdomain. This proxy type uses the metadata definition of the original type. therefore, It looks exactly like the original type, and has exactly the same instance Members. however, the instance fields do not become part of the proxy type, and then there is more discussion of the instance field Issues. This proxy type does define several (own) instance fields, but the fields are inconsistent with the original Type. instead, These fields are just used to specify which AppDomain "owns" the real object and how to find the real object in the AppDomain that owns it.</p></p><p><p>After this proxy type is defined in the target appdomain, the Createinstanceandunwrap method creates an instance of the proxy type, initializes its fields to identify the source AppDomain and the real object, A reference to the proxy object is then returned to the target Appdomain. In the Ch22-1-appdomains application, the MBRT variable is set to refer to this proxy. Note that the object returned from the Createinstanceandunwrap method is not actually an instance of the Marshalbyreftype Type. The CLR generally does not allow an object of one type to be converted to an incompatible type. In this case, however, the CLR allows for transformation because the new type and the original type have the same instance Members. In fact, calling GetType with a proxy object, it will want you to lie and say that you are a marshalbyreftype object.</p></p><p><p>however, It can be proved that the object returned from Createinstanceandunwrap is actually a reference to a proxy object, The Remotingservices.istransparentproxy method is called in the Ch22-1-appdomains application, and the reference returned by the Createinstanceandunwrap method is Passed. From the output, the Istransparentproxy method returns true, proving that a proxy is Returned.</p></p><p><p>The application then uses the proxy to invoke the SomeMethod method. Because the MBRT variable references a proxy object, the SomeMethod implemented by the proxy is Called. In the implementation of the proxy, the Information field in the proxy object is used to switch the calling thread from the default AppDomain to the new Appdomain. now, any action on the thread is run under the security policy and configuration settings of the new Appdomain. The thread then uses the GCHandle field of the proxy object to find the real object in the AppDomain and invokes the real Somethod method with the real Object.</p></p><p><p>There are two ways to prove that the calling thread is switching from the default AppDomain to the new Appdomain. In the SomeMethod method, I called Thread.getdomain (). Friendlyname. This returns "AD #2" because the thread is now running in a new appdomain, and this new AppDomain is created by calling the Appdomain.createdomain method and passing "ad #2" as the friendly name Parameter. In fact, If you debug code in a debugger and open the call stack window, the [external code] line labels where a thread crosses the AppDomain boundary.</p></p><p><p>When the true SomeMethod method returns, it returns to the Agent's SomeMethod method, and then switches the thread to the default Appdomain. The thread then executes the code in the default Appdomain.</p></p><p><p>Note: when a thread in one AppDomain calls a method in another appdomain, the thread switches between the two Appdomain. This means that the method calls across the AppDomain boundary are performed synchronously. however, at any one time, a thread can be in only one AppDomain and execute code with that Appdomain's security and configuration Settings. If you want code in multiple AppDomain to execute concurrently, create additional threads that let these threads execute the code you want in the AppDomain you Want.</p></p><p><p>The next thing the Ch22-1-appdomains application does is call the public static method unload of the AppDomain class, which forces the CLR to unload the specified AppDomain (including all assemblies loaded into it), and enforces a garbage collection. To release all objects created by code in the Unload Appdomain. This is where the default Appdomain's MBRT variable still references a valid proxy Object. however, the proxy object is no longer referencing a valid appdomain.</p></p><p><p>of course, when the default AppDomain tries to invoke the SomeMethod method using a proxy object, the implementation of the method in the proxy is Called. The implementation of the agent discovers that the AppDomain containing the real object has been Unloaded. therefore, the Proxy's SomeMethod method throws a AppDomainUnloadedException exception that tells the caller that the operation cannot be Completed.</p></p><p><p>obviously, Microsoft's CLR team has to do a lot of work to ensure proper isolation of the appdomain, but this is what they have to do to access objects across the AppDomain is being used massively, and developers are increasingly lazy about this feature. however, using the "marshal by reference" semantics for object access across AppDomain boundaries can incur some performance overhead. therefore, generally as little as possible to use this Function.</p></p><p><p>I have promised more discussion instance fields Before. A type derived from MarshalByRefObject can define an instance Field. however, These instance fields do not become part of the proxy type and are not included in a proxy object.</p></p><p><p>When you write code to read and write to an instance field of a type derived from marshalbyrefobject, the JIT compiler automatically generates code that calls System.ojbect's Fieldgetter method or Fieldsetter method to use the proxy object. These methods are private and are not documented in The. NET FrameWork SDK Documentation. Simply put, These methods use the reflection mechanism to get or set a value in a field. therefore, Although you can access fields from a type derived from marshalbyrefobject, the performance is poor because the CLR eventually calls the method to perform field access. In fact, even if the field you're trying to access is in your own appdomain, performance doesn't go Anywhere.</p></p><p><p>From a good point of view, a type derived from MarshalByRefObject should avoid defining any static Members. This is because static members are always accessed in the context of the calling Appdomain. The switch to the AppDomain does not occur when the information to which AppDomain is to be switched is included in the proxy object, but there is no proxy object when the static member is Called. It's too ugly to have a static member of a type execute in an AppDomain and have instance members execute in another appdomain.</p></p><p><p>Because the second AppDomain does not have a root, the original object referenced by the agent can be garbage collected. This is certainly not ideal. But on the other side, if the original object is left indeterminate in memory, the proxy may not be referencing it, and the original object still survives; The CLR solves this problem by using a "lease manager". After an Object's proxy is created, the CLR keeps the object alive for 5 Minutes. If only 5 minutes of the call is not made through the proxy, the object fails and the next garbage collection releases its object. Each time a call is made to an object, the lease manager renews the lease of the object to ensure that it remains alive in memory for the next 2 minutes. If you try to call it through a proxy after the object expires, the CLR throws a Remotingexception.</p></p><p><p>The default 5-minute and 2-minute tenancy settings can be modified, and you'll need to rewrite Marshalbyrefobject's virtual method initializelifetimeservices.</p></p><p><p></p></p><p><p>Demo 2: Cross-appdomain communication with "marshal by value"</p></p><p><p>Demo 2 is very familiar with demo 2. As with demo 1, the demo 2 page creates a new Appdomain. then, call the Createinstanceandunwrap method to load the same assembly into the new AppDomain and create an instance of the Marshalbyreftype type in the new Appdomain. The CLR then creates a proxy for this object, and the MBRT variable is initialized to refer to the Proxy. now, using this proxy, I'm calling Methodwithreturn. This method has no parameters, it executes in the new appdomain, creates an instance of the Marshalbyvaltype type, and returns a reference to the default Appdomain.</p></p><p><p>Marshalbyvaltype is not derived from marshalbyrefobject, so the CLR cannot define a proxy type and create an instance of the proxy type, and objects cannot be marshaled across AppDomain boundaries by Reference.</p></p><p><p>however, because Marshalbyvaltype marks the custom attribute of [Serializable], the Createinstanceandunwrap method can marshal objects by Value. The following is a description of the meaning of marshaling an object from one AppDomain (source Appdomain) to another AppDomain (the target Appdomain) by Value.</p></p><p><p>When the source AppDomain wants to send or return an object reference to the target appdomain, the CLR serializes an instance field of the object into a byte array. This byte array is copied from the source AppDomain to the target Appdomain. The CLR then deserializes the byte array in the target appdomain, which forces the CLR to load the assembly that defines the "deserialized type" into the target appdomain, if it is not already loaded. The CLR then creates an instance of the type and uses the values in the byte array to initialize the field of the object to the same value as the source Object. In other words, the CLR replicates the source object exactly in the target Appdomain. The Createinstanceandunwrap method then returns a reference to the copy, so that the object is marshaled by value across the Appdomain's boundaries.</p></p><p><p>Important: when loading an assembly, the CLR uses the policy and configuration settings of the target AppDomain (for example, The AppDomain may have a different appbase directory or a different version binding redirect). These policy differences may hinder the CLR from being set as an assembly. If an assembly is not documented, an exception is thrown and the target AppDomain does not receive an object Reference.</p></p><p><p>At this point, the objects in the source AppDomain and the objects in the target AppDomain have independent lifetimes, and their state can be changed independently. If no root in the source AppDomain keeps the source object alive, the memory of the Meta-object is reclaimed at the next garbage collection.</p></p><p><p>To prove that the object returned from the Methodwithreturn method is not a reference to the proxy object, the Ch22-1-appdomains application calls the public static method Istransparentproxy of remotingservice, and pass the reference returned by the Methodwidthreturn method as a parameter to it. Returns false to indicate that the object is a real object, not a proxy object.</p></p><p><p>now, The program calls the ToString method with the real Object. Because the MBRT variable references a real object, the real implementation of this method is called, and the thread does not switch between the Appdomain. To prove this, you can view the Debugger's Call Stack window without displaying an [AppDomain Transition] row.</p></p><p><p>To further prove that no agent is involved, the Ch22-1-appdomains application uninstalls the Appdomain. Then try calling ToString Again. This call will Succeed. Because the unloaded AppDomain heap defaults to the appdomain, there are no objects Affected. The objects that are marshaled by value are, of course, included in these Objects.</p></p><p><p>Demo 3: use non-marshaled types to communicate across AppDomain</p></p><p><p>This demo is very similar to the first two demos, all creating a new Appdomain. then, call the Createinstanceandunwrap method to load the same assembly into the new appdomain, create a Marshalbyvaltype object in the new appdomain, and let MBRT refer to a proxy for the Object.</p></p><p><p> I then use the proxy to invoke methodargandreturn, which accepts an argument. similarly, the CLR must keep the AppDomain isolated, so it cannot directly pass references to arguments to the new appdomain. If the Object's type derives from <strong> MarshalByRefObject </strong> <strong>, CLR </strong> <strong> creates a proxy for it and marshals by Reference. If the Object's type is marked with [Serializable] </strong> <strong>, the CLR </strong> <strong> serializes the object into a byte array, marshaling the byte array to the new AppDomain </strong> <strong>, and then deserializes an object graph into a byte array, passing the root of the object graph to Methodargandreturn </strong> The <strong> method. </strong></p></p><p><p> <strong> in this particular example, I pass a string </strong> <strong> object across the AppDomain </strong> <strong> boundary. The String </strong> <strong> type is not derived from MarshalByRefObject </strong> <strong>, so the CLR </strong> <strong> cannot create a proxy. fortunately, the String </strong> <strong> is marked as [Serializable] </strong> <strong>, so the CLR </strong> <strong> can marshal it by value, allowing the code to work properly. Note that for a string </strong> <strong> object, CLR </strong> <strong> takes a special optimization measure to marshal a string across the AppDomain </strong> <strong> boundary </strong> <strong> object, The CLR </strong> <strong> simply passes a reference to a string </strong> <strong> object across the boundary; does not really generate a string </strong> <strong> A copy of the Object. The CLR </strong> <strong> is able to provide this optimization when it is immutable because of the string </strong> <strong> object; so, an AppDomain </strong> <strong> It is not possible to break the field of a string </strong> <strong> object in Code. </strong></p></p><p><p><strong>in Methodargandreturn</strong> <strong>inside, I display the string to it, proving that the string spans the AppDomain</strong> <strong>Boundary. I then create</strong> <strong>An instance of the Nonmarshalabletype type and return a reference to the object to the default AppDomain</strong><strong>. Since Nonmarshalabletype</strong> <strong>is not derived from MarshalByRefObject</strong> and <strong>does not apply [Serializable]</strong> <strong>this tag, So it is not allowed to marshal objects by reference and by value-</strong> <strong>objects cannot be marshaled across AppDomain</strong> <strong>boundaries at all! To report this problem, Methodargandreturn</strong> <strong>throws a serializationexception</strong> <strong>in the default AppDomain</strong> <strong>. </strong></p></p><p><p>Section Ii: AppDomain</p></p></span>
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.