/// <summary> /// Compiles in a seperate appdomain utilitizing one of the compilers on the stack. /// </summary> public static void Compile(ErrorSink /*!*/ errorSink, CompilationParameters /*!*/ ps) { // obtain a compiler StackItem item = new StackItem(); lock (stack) { if (stack.Count > 0) { item = stack.Pop(); } } if (item.Compiler == null) { item.Compiler = ApplicationCompiler.CreateRemoteCompiler(); } // compile item.Compiler.RemoteCompile(ref errorSink, ps); // check whether the separate appdomain is not too weedy if (++item.CompileCounter == 1 || item.CompileCounter == compileCounterTreshold) { item.CompileCounter = 1; CallBackDisplay display = new CallBackDisplay(); // avoid passing the array of assemblies across appdomain boundary item.Compiler.Domain.DoCallBack(display.Handler); if (item.RemoteAssemblyCount == 0) { item.RemoteAssemblyCount = display.AssemblyCount; } else { if (display.AssemblyCount > (2 * item.RemoteAssemblyCount)) { AppDomain.Unload(item.Compiler.Domain); return; } } } // recycle the compiler lock (stack) stack.Push(item); }
public void RemoteCompile(ref ErrorSink /*!*/ errorSink, CompilationParameters /*!*/ ps) { lock (buildMutex) // TODO: do we need thread-safety (if yes, there is a better way)? { //if (++buildCounter % 10 == 0) // TODO: is it possible to estimate size of memory allocated by the domain? //{ // // if a referenced assembly gets updated then we should reload the domain as well // AppDomain.Unload(remoteCompiler.Domain); // remoteCompiler = null; //} if (remoteCompiler != null) { AppDomain.Unload(remoteCompiler.Domain); } remoteCompiler = ApplicationCompiler.CreateRemoteCompiler(); remoteCompiler.RemoteCompile(ref errorSink, ps); } }