PowerShell:在管道停止时释放对象



我想知道如何在管道停止时正确释放脚本化 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,不涉及编译。

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

(在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块或类似块,恕我直言,这将是一个伟大且急需的改进。

最新更新