使用CodeDOM将程序集添加到BuildManager导致间歇性错误

我正在使用CodeDOM在运行时创建内存中的程序集,如下所示:

public Assembly Compile(CodeCompileUnit targetUnit) { string path = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath); var compilerParameters = new CompilerParameters { GenerateInMemory = true, IncludeDebugInformation = true, TreatWarningsAsErrors = true, WarningLevel = 4, CompilerOptions = "/nostdlib", }; //For system.dll compilerParameters.ReferencedAssemblies.Add(typeof(System.Diagnostics.Debug).Assembly.Location); //For system.core.dll compilerParameters.ReferencedAssemblies.Add(typeof(System.IO.DirectoryInfo).Assembly.Location); //For Microsoft.CSharp.dll compilerParameters.ReferencedAssemblies.Add(typeof(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException).Assembly.Location); compilerParameters.ReferencedAssemblies.Add(typeof(System.Runtime.CompilerServices.CallSite).Assembly.Location); //Add other assemblies as needed. var compilerResults = new CSharpCodeProvider() .CompileAssemblyFromDom(compilerParameters, targetUnit); if (compilerResults == null) { throw new InvalidOperationException("ClassCompiler did not return results."); } if(compilerResults.Errors.HasErrors) { var errors = string.Empty; foreach (CompilerError compilerError in compilerResults.Errors) { errors += compilerError.ErrorText + "\n"; } Debug.Fail(errors); throw new InvalidOperationException("Errors occured while compiling dynamic classes:\n" + errors); } var dynamicAssembly = compilerResults.CompiledAssembly; return dynamicAssembly; } 

上面生成的程序集在ASPNET主机启动时添加到BuildManager:

 [assembly: WebActivatorEx.PreApplicationStartMethod(typeof(MyWebApp.MyStartup), "Start")] [assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(MyWebApp.MyStartup), "Stop")] namespace MyWebApp { public static class MyStartup { public static void Start() { System.Reflection.Assembly assembly = GetDynamicAssembly(); System.Web.Compilation.BuildManager.AddReferencedAssembly(assembly); } private static System.Reflection.Assembly GetDynamicAssembly() { //create and return dynamic assemblies using Codedom here var unit = GetCompilationUnit(); //elided for brevity return Compile(unit); } public static void Stop() { //do cleanup if needed } } } 

以上工作大部分,但有时,我不断得到以下错误,没有明确的原因指示:

 [NullReferenceException: Object reference not set to an instance of an object.] System.CodeDom.Compiler.CodeDomProvider.TryGetProbableCoreAssemblyFilePath(CompilerParameters parameters, String& coreAssemblyFilePath) +245 Microsoft.CSharp.CSharpCodeGenerator.CmdArgsFromParameters(CompilerParameters options) +149 Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(CompilerParameters options, String[] fileNames) +366 Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromFileBatch(CompilerParameters options, String[] fileNames) +160 System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromFile(CompilerParameters options, String[] fileNames) +23 System.Web.Compilation.AssemblyBuilder.Compile() +884 System.Web.Compilation.BuildProvidersCompiler.PerformBuild() +9519768 System.Web.Compilation.ApplicationBuildProvider.GetGlobalAsaxBuildResult(Boolean isPrecompiledApp) +9929000 System.Web.Compilation.BuildManager.CompileGlobalAsax() +44 System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled() +269 [HttpException (0x80004005): Object reference not set to an instance of an object.] System.Web.Compilation.BuildManager.ReportTopLevelCompilationException() +62 System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled() +427 System.Web.Compilation.BuildManager.CallAppInitializeMethod() +31 System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +535 [HttpException (0x80004005): Object reference not set to an instance of an object.] System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +9930508 System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +101 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +254 

我查看了csharpcodeprovider中CmdArgsFromParamters的源代码,它调用了TryGetProbableCoreAssemblyFilePath ,它似乎正在寻找要设置的CoreAssemblyFileName

  string coreAssemblyFileName = options.CoreAssemblyFileName; if (String.IsNullOrWhiteSpace(options.CoreAssemblyFileName)) { string probableCoreAssemblyFilePath; if(CodeDomProvider.TryGetProbableCoreAssemblyFilePath(options, out probableCoreAssemblyFilePath)) { coreAssemblyFileName = probableCoreAssemblyFilePath; } 

我是否需要明确设置CoreAssemblyFileName ,如果是这样,应该将其设置为什么? 关于此的文档似乎有点稀疏。

重申一下,上述错误会间歇性地发生,我很困惑,因为根本原因是什么?