dotnet publish 间歇性失败,因为 DLL 正在使用中,即使在回收应用程序池之后也是如此

dotnet publish fails intermittently because DLL is in use, even after recycling the app pool

我正在开发一个 ASP.NET Core 3.1 网络应用程序项目,我注意到一键式网络部署(我为此设置了一个文件夹配置文件)不起作用,因为我的网站文件夹中的 DLL正在被另一个进程使用(可能 w3wp.exe)。我对 ASP.NET Core 还是很陌生,但这对我来说从来不是常规 ASP.NET 的问题。无论如何,我发现回收应用程序池可以暂时修复它,直到 1-2 发布后它再次发生。

我发现 建议让项目的 post-build 事件在发布前自动回收应用程序池,所以我这样实现:

ECHO ON
%SYSTEMROOT%\System32\inetsrv\appcmd recycle apppool /apppool.name:"NeatF2P"
dotnet publish --output C:\Websites\NeatF2P --force --no-build
pause

问题是,它并不总是有效。我构建,在输出 window 中看到 "NeatF2P" successfully recycled,但之后仍然出现相同的错误。这是完整的输出日志:

Build started...
1>------ Build started: Project: NeatF2PWebsite, Configuration: Debug Any CPU ------
1>NeatF2PWebsite -> C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\bin\Debug\netcoreapp3.1\NeatF2PWebsite.dll
1>NeatF2PWebsite -> C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\bin\Debug\netcoreapp3.1\NeatF2PWebsite.Views.dll
1>"NeatF2P" successfully recycled
1>Microsoft (R) Build Engine version 16.9.0+57a23d249 for .NET
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>
1>C:\Program Files\dotnet\sdk.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(238,5): warning MSB3026: Could not copy "obj\Debug\netcoreapp3.1\NeatF2PWebsite.dll" to "C:\Websites\NeatF2P\NeatF2PWebsite.dll". Beginning retry 1 in 1000ms. The process cannot access the file 'C:\Websites\NeatF2P\NeatF2PWebsite.dll' because it is being used by another process.  [C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj]
1>C:\Program Files\dotnet\sdk.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(238,5): warning MSB3026: Could not copy "obj\Debug\netcoreapp3.1\NeatF2PWebsite.dll" to "C:\Websites\NeatF2P\NeatF2PWebsite.dll". Beginning retry 2 in 1000ms. The process cannot access the file 'C:\Websites\NeatF2P\NeatF2PWebsite.dll' because it is being used by another process.  [C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj]
1>C:\Program Files\dotnet\sdk.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(238,5): warning MSB3026: Could not copy "obj\Debug\netcoreapp3.1\NeatF2PWebsite.dll" to "C:\Websites\NeatF2P\NeatF2PWebsite.dll". Beginning retry 3 in 1000ms. The process cannot access the file 'C:\Websites\NeatF2P\NeatF2PWebsite.dll' because it is being used by another process.  [C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj]
1>C:\Program Files\dotnet\sdk.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(238,5): warning MSB3026: Could not copy "obj\Debug\netcoreapp3.1\NeatF2PWebsite.dll" to "C:\Websites\NeatF2P\NeatF2PWebsite.dll". Beginning retry 4 in 1000ms. The process cannot access the file 'C:\Websites\NeatF2P\NeatF2PWebsite.dll' because it is being used by another process.  [C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj]
1>C:\Program Files\dotnet\sdk.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(238,5): warning MSB3026: Could not copy "obj\Debug\netcoreapp3.1\NeatF2PWebsite.dll" to "C:\Websites\NeatF2P\NeatF2PWebsite.dll". Beginning retry 5 in 1000ms. The process cannot access the file 'C:\Websites\NeatF2P\NeatF2PWebsite.dll' because it is being used by another process.  [C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj]
1>C:\Program Files\dotnet\sdk.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(238,5): warning MSB3026: Could not copy "obj\Debug\netcoreapp3.1\NeatF2PWebsite.dll" to "C:\Websites\NeatF2P\NeatF2PWebsite.dll". Beginning retry 6 in 1000ms. The process cannot access the file 'C:\Websites\NeatF2P\NeatF2PWebsite.dll' because it is being used by another process.  [C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj]
1>C:\Program Files\dotnet\sdk.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(238,5): warning MSB3026: Could not copy "obj\Debug\netcoreapp3.1\NeatF2PWebsite.dll" to "C:\Websites\NeatF2P\NeatF2PWebsite.dll". Beginning retry 7 in 1000ms. The process cannot access the file 'C:\Websites\NeatF2P\NeatF2PWebsite.dll' because it is being used by another process.  [C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj]
1>C:\Program Files\dotnet\sdk.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(238,5): warning MSB3026: Could not copy "obj\Debug\netcoreapp3.1\NeatF2PWebsite.dll" to "C:\Websites\NeatF2P\NeatF2PWebsite.dll". Beginning retry 8 in 1000ms. The process cannot access the file 'C:\Websites\NeatF2P\NeatF2PWebsite.dll' because it is being used by another process.  [C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj]
1>C:\Program Files\dotnet\sdk.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(238,5): warning MSB3026: Could not copy "obj\Debug\netcoreapp3.1\NeatF2PWebsite.dll" to "C:\Websites\NeatF2P\NeatF2PWebsite.dll". Beginning retry 9 in 1000ms. The process cannot access the file 'C:\Websites\NeatF2P\NeatF2PWebsite.dll' because it is being used by another process.  [C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj]
1>C:\Program Files\dotnet\sdk.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(238,5): warning MSB3026: Could not copy "obj\Debug\netcoreapp3.1\NeatF2PWebsite.dll" to "C:\Websites\NeatF2P\NeatF2PWebsite.dll". Beginning retry 10 in 1000ms. The process cannot access the file 'C:\Websites\NeatF2P\NeatF2PWebsite.dll' because it is being used by another process.  [C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj]
1>C:\Program Files\dotnet\sdk.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(238,5): error MSB3027: Could not copy "obj\Debug\netcoreapp3.1\NeatF2PWebsite.dll" to "C:\Websites\NeatF2P\NeatF2PWebsite.dll". Exceeded retry count of 10. Failed.  [C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj]
1>C:\Program Files\dotnet\sdk.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(238,5): error MSB3021: Unable to copy file "obj\Debug\netcoreapp3.1\NeatF2PWebsite.dll" to "C:\Websites\NeatF2P\NeatF2PWebsite.dll". The process cannot access the file 'C:\Websites\NeatF2P\NeatF2PWebsite.dll' because it is being used by another process. [C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj]
1>Press any key to continue . . .
1>C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj(24,5): error MSB3073: The command "ECHO ON
1>C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj(24,5): error MSB3073: %SYSTEMROOT%\System32\inetsrv\appcmd recycle apppool /apppool.name:"NeatF2P"
1>C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj(24,5): error MSB3073: dotnet publish --output C:\Websites\NeatF2P --force --no-build
1>C:\Dev\Personal\NeatF2PWebsite\NeatF2PWebsite\NeatF2PWebsite.csproj(24,5): error MSB3073: pause" exited with code 1.
1>Done building project "NeatF2PWebsite.csproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

如果我稍等片刻然后再次尝试构建,有时会成功,有时却失败。手动回收应用程序池(在 IIS 中)有时会起作用,尽管它不应该做任何命令不能做的事情,对吧?为什么会这样?

回收就像重新启动它,它可能会在另一个构建尝试获取文件句柄之前获取文件句柄,也可能不会。发布后停止并重启

@L.Trabacchin的回答让我走上了正轨。如果我修改 post-build 事件命令以在 dotnet publish 命令后停止并重新启动应用程序池:

ECHO ON
%SYSTEMROOT%\System32\inetsrv\appcmd stop apppool /apppool.name:"NeatF2P"
dotnet publish --output C:\Websites\NeatF2P --force --no-build
%SYSTEMROOT%\System32\inetsrv\appcmd start apppool /apppool.name:"NeatF2P"

这还没有失败,我已经做了十几个版本。