我正在使用New-Object System.Management.Automation.PipelineStoppedException 要停止管道OK..works ..
但是如何在下一个cmdlet中测试是否可以停止?
Foo1 | foo2 | foo3
在foo1停止,但转到foo2。我想测试是否在foo1中停止了在每个函数中停止
function foo1 {
process {
try {
#do
} catch {
New-Object System.Management.Automation.PipelineStoppedException
}
}
}
仍然会转到下一个cmdlet,因错误而停止我想在每个下一个cmdlet中停止.. :)
谢谢!!!
答案 0 :(得分:2)
您误解了管道的工作原理。当一系列对象被发送到管道时,每个单独的对象在处理下一个对象之前通过整个管道。请考虑以下功能:
function First() {
process {
Write-Host "First: $_";
$_
}
}
function Second() {
process {
Write-Host "Second: $_";
}
}
第一个函数输出“First”和管道对象的值,然后传递对象。第二个仅输出“Second”和管道对象。现在,当您将数组推送到由这两个函数组成的管道时,您希望看到什么?
实际结果如下:
PS C:\Users\Lauri> ,1,2,3 | first | second
First: 1
Second: 1
First: 2
Second: 2
First: 3
Second: 3
现在,有了这个信息,我们可以推断出当管道中的函数或cmdlet抛出异常以停止处理时,整个管道就会停止。但我们也可以轻松验证它。让我们修改First如下:
function First() {
process {
throw New-Object System.Management.Automation.PipelineStoppedException
}
}
然后再次尝试相同的管道:
PS C:\Users\Lauri> ,1,2,3 | first | second
结果为空,因为第一个对象传递给“First”的那一刻,它会抛出异常,整个管道都会中止。
总之,您无法测试处理是否在管道中进一步中止,因为执行将永远不会到达。
[编辑]另一个有趣的小问题:首先运行所有函数的Begin块,并且End块都是最后运行的,所以如果你在管道中更高的Process块中抛出一个异常,那么Begin块就是所有管道功能都已经运行:
function First() {
begin {
Write-Host "First begin"
}
process {
throw New-Object System.Management.Automation.PipelineStoppedException
}
end {
Write-Host "First end"
}
}
function Second() {
begin {
Write-Host "Second begin"
}
process {
Write-Host "Second: $_"
}
end {
Write-Host "Second end"
}
}
PS C:\Users\Lauri> ,1,2,3 | first | second
First begin
Second begin
[编辑2]
另一个可能有趣的结果是,如果发生异常并且您希望管道在此之后继续,则需要在catch块中返回捕获它的内容:
function CauseException {
throw New-Object Exception
}
function First() {
process {
try {
CauseException
} catch {
"Error"
}
}
}
function Second() {
process {
Write-Host "Second: $_"
}
}
PS C:\Users\Lauri> ,1,2,3 | first | second
Second: Error
Second: Error
Second: Error