privatevoidValidatePath(string path) { if (path == null) thrownewArgumentNullException("path"); if (!System.IO.File.Exists(path)) thrownewArgumentException(String.Format("path \"{0}\" does not exist", path)); } }
privatevoidValidatePath(string path) { if (path == null) thrownew ArgumentNullException("path"); if (!System.IO.File.Exists(path)) thrownew ArgumentException(String.Format("path \"{0}\" does not exist", path)); } }
classProgram { /// <summary> /// Show how to pass an object by reference directly into another appdomain /// without serializing it at all. /// </summary> /// <param name="args"></param> [LoaderOptimization(LoaderOptimization.MultiDomainHost)] staticpublicvoidMain(string[] args){ for (int i = 0; i < 10000; i++) // try it often to see how the AppDomains do behave { // To load our assembly appdomain neutral we need to use MultiDomainHost // on our hosting and child domain If not we would get different Method // tables for the same types which would result in InvalidCastExceptions // for the same type. // Prerequisite for MultiDomainHost is that the assembly we share the data // is a) Installed into the GAC (which requires as strong name as well) If // you would use MultiDomain then it would work but all AppDomain neutral // assemblies will never be unloaded. var other = AppDomain.CreateDomain( "Test" + i.ToString(), AppDomain.CurrentDomain.Evidence, new AppDomainSetup { LoaderOptimization = LoaderOptimization.MultiDomainHost, });
// Create gate object in other appdomain DomainGate gate = (DomainGate)other.CreateInstanceAndUnwrap( Assembly.GetExecutingAssembly().FullName, typeof(DomainGate).FullName);
// now lets create some data CrossDomainData data = newCrossDomainData(); data.Input = Enumerable.Range(0, 10).ToList();
// process it in other AppDomain DomainGate.Send(gate, data);
// Display result calculated in other AppDomain Console.WriteLine("Calculation in other AppDomain got: {0}", data.Aggregate);
AppDomain.Unload(other); // check in debugger now if UnitTests.dll has been unloaded. Console.WriteLine("AppDomain unloaded"); } }
///<summary> /// Enables sharing of data between appdomains as plain objects without any /// marsalling overhead. ///</summary> classDomainGate : MarshalByRefObject { ///<summary> /// Operate on a plain object which is shared from another AppDomain. ///</summary> ///<param name="gcCount">Total number of GCs</param> ///<param name="objAddress">Address to managed object.</param> publicvoidDoSomething(int gcCount, IntPtr objAddress) { if (gcCount != ObjectAddress.GCCount) { thrownew NotSupportedException( "During the call a GC did happen. Please try again."); }
// If you get an exception here disable under Projces/Debugging/Enable // Visual Studio Hosting Process The appdomain which is used there seems to // use LoaderOptimization.SingleDomain CrossDomainData data = (CrossDomainData)PtrConverter<Object>.Default.ConvertFromIntPtr( objAddress); ;
// process input data from other domain foreach (var x in data.Input) { Console.WriteLine(x); }
OtherAssembliesUsage user = new OtherAssembliesUsage();
// generate output data data.Aggregate = data.Input.Aggregate((x, y) => x + y); }
publicstaticvoidSend(DomainGate gate, object o) { var old = GCSettings.LatencyMode; try { GCSettings.LatencyMode = GCLatencyMode.Batch; // try to keep the GC out of our stuff var addandGCCount = ObjectAddress.GetAddress(o); gate.DoSomething(addandGCCount.Value, addandGCCount.Key); } finally { GCSettings.LatencyMode = old; } } }