我在通过命令行发布解决方案时遇到了问题。在各个项目中,它会间歇性地失败,但偶尔会成功。我既遇到了空引用错误,也遇到了“运行线程的应用程序域已被卸载”的错误,这可能只是带有竞争条件的空引用。它似乎只会在具有 Web 服务(原始 .asmx 和带有 .svc 或无文件激活的 WCF)的项目上失败。它有时成功的事实使我认为这不是我们代码的问题,尽管可能有一些更改可以减轻潜在原因(无论是什么)。
我发现其他人也遇到了类似的问题,但是他们要么没有得到答案,要么提供的解决方案对我无效。还有其他的想法吗? 编辑: 这是我正在使用的命令行:
这是一些控制台输出(已重定向到文件)的内容:
任何一个变量都可能为null,导致异常:result、HostingEnvironment和compiledAssemblyBase。
我尝试/检查的内容:
- 我运行了
tfpt scorch
来清理任何本地更改,包括构建输出,但没有成功,所以我知道这不是源目录的问题。 - 我清除了位于
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files
(我们使用的是 32 位)的临时文件,似乎进展更多了,但仍然存在问题。在另一次发布后,目录仍然为空,所以可能与此无关。 - 通过 Process Monitor,我发现
aspnet_compiler
正在写入到%LocalAppData%\Temp\Temporary ASP.NET Files
。清除这些文件有时似乎有效,或者可能只是我运气好,但然后它又开始失败了。我没有发现其他可能相关的内容。 - 确保我有足够的 RAM,似乎没有什么区别。
- 单线程运行 msbuild,没有区别
- 从命令行运行 aspnet_compiler(从 MSBuild 日志输出中获取命令),总是成功的
- 没有压缩的文件夹
- 我使用的是最新稳定版的 Visual Studio(VS 2013 更新 2),但这不应该有影响,因为我是从命令行运行的,使用的可执行文件在框架目录中。
- 一些失败的项目中没有 App_Code 文件夹
构建输出没有提供任何有用的信息,所以我设置了 DebugDiag 来在崩溃时输出。以下是结果:
DetailID = 1
Count: 1
Type: System.NullReferenceException
Message:
Stack:
System.Web.Compilation.DiskBuildResultCache.CacheBuildResult(System.String, System.Web.Compilation.BuildResult, Int64, System.DateTime)
System.Web.Compilation.BuildManager.CacheBuildResultInternal(System.String, System.Web.Compilation.BuildResult, Int64, System.DateTime)
System.Web.Compilation.WebDirectoryBatchCompiler.CacheAssemblyResults(System.Web.Compilation.AssemblyBuilder, System.CodeDom.Compiler.CompilerResults)
System.Web.Compilation.WebDirectoryBatchCompiler.CompileAssemblyBuilder(System.Web.Compilation.AssemblyBuilder)
System.Web.Compilation.WebDirectoryBatchCompiler.CompileAssemblyBuilderParallel(System.Collections.ICollection)
System.Web.Compilation.WebDirectoryBatchCompiler.CompileNonDependentBuildProviders(System.Collections.ICollection)
System.Web.Compilation.WebDirectoryBatchCompiler.Process()
System.Web.Compilation.BuildManager.BatchCompileWebDirectoryInternal(System.Web.Hosting.VirtualDirectory, Boolean)
System.Web.Compilation.BuildManager.BatchCompileWebDirectory(System.Web.Hosting.VirtualDirectory, System.Web.VirtualPath, Boolean)
System.Web.Compilation.BuildManager.PrecompileWebDirectoriesRecursive(System.Web.Hosting.VirtualDirectory, Boolean)
System.Web.Compilation.BuildManager.PrecompileAppInternal(System.Web.VirtualPath, System.Collections.Generic.IEnumerable`1<System.String>)
System.Web.Compilation.BuildManager.PrecompileApp(System.Web.VirtualPath, System.Collections.Generic.IEnumerable`1<System.String>)
System.Web.Compilation.BuildManager.PrecompileApp(System.Web.Compilation.ClientBuildManagerCallback, System.Collections.Generic.IEnumerable`1<System.String>)
System.Web.Compilation.BuildManagerHost.PrecompileApp(System.Web.Compilation.ClientBuildManagerCallback, System.Collections.Generic.List`1<System.String>)
[GCFrame]
[GCFrame]
[ContextTransitionFrame]
[GCFrame]
[GCFrame]
[GCSafeCollectionFrame]
[GCSafeCollectionFrame]
[GCSafeCollectionFrame]
[GCSafeCollectionFrame]
[GCSafeCollectionFrame]
[GCSafeCollectionFrame]
[GCSafeCollectionFrame]
[TPMethodFrame]
*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\System.Web\3d247ccfb800c38a29cf91c27a6339da\System.Web.ni.dll
Module load completed but symbols could not be loaded for C:\Windows\assembly\NativeImages_v4.0.30319_32\System.Web\3d247ccfb800c38a29cf91c27a6339da\System.Web.ni.dll
System.Web.Compilation.ClientBuildManager.PrecompileApplication(System.Web.Compilation.ClientBuildManagerCallback)
*** ERROR: Module load completed but symbols could not be loaded for C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe
[GCFrame]
DetailID = 2
Count: 1
Type: System.NullReferenceException
Message: Object reference not set to an instance of an object.
Stack:
[GCFrame]
[GCFrame]
[GCFrame]
[GCSafeCollectionFrame]
[GCSafeCollectionFrame]
[GCSafeCollectionFrame]
[GCSafeCollectionFrame]
[GCSafeCollectionFrame]
[GCSafeCollectionFrame]
[GCSafeCollectionFrame]
[TPMethodFrame]
System.Web.Compilation.ClientBuildManager.PrecompileApplication(System.Web.Compilation.ClientBuildManagerCallback, Boolean)
System.Web.Compilation.ClientBuildManager.PrecompileApplication(System.Web.Compilation.ClientBuildManagerCallback)
System.Web.Compilation.Precompiler.Main(System.String[])
[GCFrame]
我发现其他人也遇到了类似的问题,但是他们要么没有得到答案,要么提供的解决方案对我无效。还有其他的想法吗? 编辑: 这是我正在使用的命令行:
"C:\Program Files (x86)\MSBuild\12.0\bin\MSBuild.exe" Solution.sln /t:Build /m:1 /p:Configuration=Prod /p:Platform="Mixed Platforms" /p:DeployOnBuild=true /p:PublishProfile=Prod /p:AutoParameterizationWebConfigConnectionStrings=false /v:diag > out.txt
这是一些控制台输出(已重定向到文件)的内容:
Target "AspNetPreCompile: (TargetId:3773)" in file "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\Web\Transform\Microsoft.Web.Publishing.AspNetCompileMerge.targets" from project "C:\Source\Project\Project.csproj" (target "PipelineAspNetCompileMergePhase" depends on it):
Task "AspNetCompiler" (TaskId:2474)
Task Parameter:PhysicalPath=C:\Source\Project\obj\x86\Release\AspnetCompileMerge\Source (TaskId:2474)
Task Parameter:TargetPath=C:\Source\Project\obj\x86\Release\AspnetCompileMerge\TempBuildDir (TaskId:2474)
Task Parameter:VirtualPath=/ (TaskId:2474)
Task Parameter:Debug=False (TaskId:2474)
Task Parameter:Updateable=False (TaskId:2474)
Task Parameter:ToolPath=C:\Windows\Microsoft.NET\Framework\v4.0.30319 (TaskId:2474)
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v / -p C:\Source\Project\obj\x86\Release\AspnetCompileMerge\Source C:\Source\Project\obj\x86\Release\AspnetCompileMerge\TempBuildDir (TaskId:2474)
Microsoft (R) ASP.NET Compilation Tool version 4.0.30319.34209 (TaskId:2474)
Utility to precompile an ASP.NET application (TaskId:2474)
Copyright (C) Microsoft Corporation. All rights reserved. (TaskId:2474)
(TaskId:2474)
ASPNETCOMPILER : error ASPRUNTIME: Object reference not set to an instance of an object. [C:\Source\Project\Project.csproj]
The command exited with code 1. (TaskId:2474)
Done executing task "AspNetCompiler" -- FAILED. (TaskId:2474)
Done building target "AspNetPreCompile" in project "Project.csproj" -- FAILED.: (TargetId:3773)
正如您所见,msbuild诊断输出并不是很有用。
编辑2: 尝试调试aspnet_compiler以更好地解决问题。我启动了gflags.exe以启用自动附加到调试器。我能够在NullReferenceException上中断,但我无法加载System.Web的符号。它来自C:\Windows\Microsoft.Net\assembly\GAC_32\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll。
根据堆栈跟踪,它在这个方法中失败:
internal override void CacheBuildResult(string cacheKey, BuildResult result, long hashCode, DateTime utcStart)
{
if (!result.CacheToDisk)
return;
if (HostingEnvironment.ShutdownInitiated)
{
BuildResultCompiledAssemblyBase compiledAssemblyBase = result as BuildResultCompiledAssemblyBase;
if (compiledAssemblyBase == null)
return;
this.MarkAssemblyAndRelatedFilesForDeletion(compiledAssemblyBase.ResultAssembly.GetName().Name);
}
else
new PreservationFileWriter(this.PrecompilationMode).SaveBuildResultToFile(this.GetPreservedDataFileName(cacheKey), result, hashCode);
}
任何一个变量都可能为null,导致异常:result、HostingEnvironment和compiledAssemblyBase。
/v:diag
。 - Nelson Rothermel