.NET 8 IIS应用通过Azure DevOps部署时间歇性出现ERROR_FILE_IN_USE错误
.NET 8 ASP.NET Core应用部署到IIS时间歇性文件锁定问题
问题描述
我正在将ASP.NET Core应用从.NET 6迁移至.NET 8,并部署到运行于Azure虚拟机(VM)的IIS服务器上。该VM仅安装了.NET 8 Hosting Bundle。迁移完成后,通过Azure DevOps流水线的IIS Web App Deploy任务进行部署的流程大多正常,但遇到了间歇性问题:部分发布失败,部分成功。
失败日志片段
##[section]Starting: IIS Web App Deploy ... [command]"...msdeploy.exe" -verb:sync -source:package='C:\azagent\A6\_work\r1\a\temp_web_package_xyz.zip' -dest:contentPath='Default Web Site' -enableRule:AppOffline -useChecksum -enableRule:DoNotDeleteRule Info: Updating file (Default Web Site\Approval.DAL.dll). Error: The process '...msdeploy.exe' failed with exit code 4294967295 ... ##[error]Error Code: ERROR_FILE_IN_USE More Information: Web Deploy cannot modify the file 'Approval.DAL.dll' on the destination because it is locked by an external process. In order to allow the publish operation to succeed, you may need to either restart your application to release the lock, or use the AppOffline rule handler for .Net applications on your next publish attempt. ...
应用信息
- 目标框架为.NET 8的ASP.NET Core应用(已从.NET 6迁移)
- IIS服务器:运行于Azure VM,仅安装了.NET 8 Hosting Bundle(除安装该组件外未对VM做其他操作)
已尝试操作
- 确认VM仅安装了.NET 8 Hosting Bundle。
- 记录到文件锁定发生在“Default Web Site”目录下的Approval.DAL.dll文件。
核心问题
- 通过MSDeploy部署.NET 8应用时,Approval.DAL.dll间歇性被锁定的原因是什么?
- 如何可靠解决或规避该问题以确保所有部署均成功?
问题分析与解决方案
间歇性文件锁定的原因
- AppOffline规则未完全生效:尽管部署命令启用了
-enableRule:AppOffline,但该规则依赖IIS应用池回收机制,若请求正在处理中,IIS可能延迟回收进程,导致DLL仍被ASP.NET Core进程锁定。 - .NET 8程序集加载策略调整:相比.NET 6,.NET 8对程序集加载的逻辑有优化,部分场景下程序集的锁定时长会延长,尤其是应用包含热重载、动态加载程序集逻辑时。
- IIS默认配置未优化:Azure VM上的IIS默认设置中,应用池的回收阈值、闲置超时等参数未调整,进程长时间运行后可能残留未释放的文件句柄。
- 并发请求干扰:部署期间若有用户请求或后台任务在运行,会持续占用Approval.DAL.dll,导致MSDeploy无法替换文件。
可靠解决/规避方案
1. 强制应用池启停(最直接有效)
在MSDeploy部署前,通过PowerShell任务先停止目标应用池,部署完成后再启动,确保进程完全释放文件:
# 停止目标应用池 Stop-WebAppPool -Name "DefaultAppPool" # 等待2秒确保进程彻底终止 Start-Sleep -Seconds 2 # 执行原MSDeploy部署任务 # 部署完成后启动应用池 Start-WebAppPool -Name "DefaultAppPool"
2. 优化AppOffline规则执行
确保AppOffline规则能正确生成app_offline.htm文件,让IIS立即回收应用池。可在部署包中提前添加空的app_offline.htm,或调整MSDeploy参数强制生成:
msdeploy.exe -verb:sync -source:package='[包路径]' -dest:contentPath='Default Web Site' -enableRule:AppOffline -setParam:name="AppOffline",value="true" -useChecksum -enableRule:DoNotDeleteRule
3. 调整IIS应用池配置
- 设置固定回收时间:在IIS管理器中为目标应用池设置“回收工作进程(分钟)”(如30分钟),定期释放进程资源。
- 启用快速失败保护:当应用池连续崩溃多次时自动重启,避免僵尸进程锁定文件。
- 缩短闲置超时:将闲置超时设置为5分钟,无请求时自动回收进程,减少文件锁定概率。
4. 利用.NET 8部署特性优化
- 单文件发布:将应用发布为单文件,减少单个DLL被锁定的场景。
- 分层编译:启用分层编译优化程序集加载逻辑,降低文件锁定时长。
5. 强制终止ASP.NET Core进程(极端情况)
若应用池停止仍无法释放文件,可直接终止对应的dotnet.exe进程(注意:会中断正在处理的请求,建议低峰时段执行):
Get-Process dotnet | Where-Object {$_.CommandLine -match "Default Web Site"} | Stop-Process -Force
内容的提问来源于stack exchange,提问作者mokhtar sayed
相关产品推荐
相关产品推荐

