PowerShell:管道停止时处置对象

时间:2019-01-29 11:13:08

标签: powershell pipeline dispose cmdlets cmdlet

我想知道当管道停止时如何正确地将对象放置在脚本cmdlet中。

通常,我将在begin块中初始化一次性对象,在process块中使用它,最后将其放置在end块中:

function Example {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline = $true)]
        [byte]$Value
    )
    begin {
        $stream = New-Object System.IO.MemoryStream
    }
    process {
        $stream.WriteByte($value)
    }
    end {
        $stream.Dispose()
    }
}

但是当管道停止时,end块不会执行(例如,使用 Ctrl + C )。而且我无法将对象放置在process块中,因为在管道的下一步中需要它。

我发布了一种可能的方法作为答案。但是还有其他更强大的解决方案吗?

(注意:这仅是关于脚本化cmdlet的,未经编译。)

1 个答案:

答案 0 :(得分:2)

这是我想出的一种解决方法:

(在Powershell v5中测试)

function Example {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline = $true)]
        [byte]$Value
    )
    begin {
        $stream = New-Object System.IO.MemoryStream
    }
    process {
        try {
            $dispose = $true
            $stream.WriteByte($value)
            # indicate that the process block finished normally
            $dispose = $false
        }
        finally {
            # detect stopped pipeline
            if ($dispose) {
                if ($stream) {
                    $stream.Dispose()
                    $stream = $null
                }
            }
        }
    }
    end {
        # regular dispose
        if ($stream) {
            $stream.Dispose()
        }
    }
}

显然,Github上要求引入一个新的Dispose块或类似的块,恕我直言,这是一个很大且非常需要的改进。