1

我正在使用 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 中停止..:)

谢谢 !!!

4

1 回答 1

2

您误解了管道的工作原理。当一系列对象被发送到管道时,每个单独的对象都会在处理下一个对象之前通过整个管道。考虑以下函数:

function First() {
    process {
        Write-Host "First: $_";
        $_
    }
}

function Second() {
    process {
        Write-Host "Second: $_";
    }
}

第一个函数输出“First”和管道对象的值,然后传递该对象。第二个仅输出“第二个”和管道对象。现在,当您将数组推送到由这两个函数组成的管道时,您希望看到什么?

实际结果是这样的:

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
于 2010-05-26T17:46:40.010 回答