如何订阅PowerShell作业在调用Stop-Job时触发的事件?
PowerShell作业中响应Stop-Job的取消机制问题
问题现象
以下代码演示:在PowerShell作业中调用的理论上可取消的长时间运行.NET方法,即使调用Stop-Job停止作业,仍会运行至完成:
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew() $jobRunning = [System.Threading.EventWaitHandle]::new($false,'ManualReset','event_1f242755') $job = Start-Job { $jobRunning = [System.Threading.EventWaitHandle]::new($false,'ManualReset','event_1f242755') $jobRunning.Set() [System.Threading.Tasks.Task]::Delay( 3000 # int millisecondsDelay <#?#> # System.Threading.CancellationToken cancellationToken ).Wait() } $jobRunning.WaitOne() | Out-Null Start-Sleep -Milliseconds 200 $job | Stop-Job | Wait-Job | Out-Null $stopwatch.Elapsed | Select-Object TotalSeconds
典型输出:
TotalSeconds : 3.2555954
输出表明Task::Delay()等待了完整的3000毫秒才结束。这类.NET任务通常可通过创建任务时传入CancellationToken取消,Task.Delay()也有支持该令牌的重载。此前通过订阅PosixSignal.SIGINT创建取消令牌在控制台pwsh.exe中可被CTRL+C触发,但在pwsh.exe作业环境中该事件不会触发。
问题:是否存在可在作业内部订阅、在调用Stop-Job时触发的事件?
当前解决方案与进展
可以通过反射订阅非公开事件实现Stop-Job触发时取消.NET任务的需求。
目前已有相关提案建议通过公共API暴露此类事件,还有更详尽的功能提案、RFC文档及代码拉取请求正在推进,期待这些改进能尽快整合到PowerShell正式版本中。
内容的提问来源于stack exchange,提问作者alx9r
相关产品推荐
相关产品推荐

