Having an async task finish after parent process is killed
我正在尝试在 TFSBuild 完成后删除一个目录 (3gb)。我将任务放在 try finally 块中,以便它始终执行。问题是当手动停止构建时,如果需要 > 1 分钟左右,任务就会被终止。 TFSBuild 认为构建挂起,因为它需要很长时间才能停止。
我尝试了以下方法无济于事:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | static void Main(string[] args) { ThreadPool.QueueUserWorkItem(s => DeleteDir(@"C:\\292\\Sources", @"C:\\testdel\\del.bat")); } static void DeleteDir(string path, string batchDir) { var process = new Process { StartInfo = { Arguments = string.Format("{0}", path) } }; process.StartInfo.FileName = batchDir; process.Start(); } } |
这是批处理文件的内容:
1 | del %1 /f /s /Q |
我也尝试过使用 Directory.Delete 等。
TFSBuild 执行任务然后停止构建,但删除任务没有完成。如果我不称它为异步,那么它只会在 ~1 分钟后终止删除任务。
如何在父进程被杀死后执行这个删除任务?
诀窍是启动另一个进程来执行删除。 Powershell 是我的助手。
我有一个名为 Spawn-Cmd.ps1 的实用程序脚本,它为我创建了一个批处理文件并启动它。请注意,它也可以启动 exe 或其他 powershell 进程,但我使用批处理文件。
1 2 3 4 5 6 7 | param([string]$cmdToSpawn) $temp = [IO.Path]::GetTempFileName() + '.cmd' Out-File -FilePath $temp -InputObject $cmdToSpawn -Encoding ASCII Start-Process -FilePath $temp -WindowStyle Hidden |
接下来修改您的 tfs 构建脚本以调用该脚本。这是一个示例 msbuild 文件。
1 2 3 4 5 6 7 8 9 10 11 | <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="SpawnDelete" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <Target Name="SpawnDelete"> <PropertyGroup> <Cmd>rd /s /q "z:\\path\\to\\folder"</Cmd> </PropertyGroup> <Exec Command="powershell -file Spawn-Cmd.ps1"$(Cmd)"" /> </Target> </Project> |
无论 tfsbuild 进程发生什么,该命令都会运行完成。
请注意,这篇文章中还有一些其他选项可以实现这一点:MSBuild exec task without blocking