PowerShell: удаление объектов после остановки конвейера - PullRequest
0 голосов
/ 29 января 2019

Мне было интересно, как правильно расположить объекты в скриптовых командлетах, когда конвейер был остановлен.

Обычно я инициализировал бы одноразовый объект в блоке 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, потому что он мне нужен для следующего шага в конвейере.

Я опубликовал один из возможных подходов в качестве ответа.Но есть ли более надежное решение?

(Примечание: речь идет только о скриптовых командлетах, а не скомпилированных.)

1 Ответ

0 голосов
/ 29 января 2019

Это один из обходных путей, который я предложил:

(протестировано в 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 блок или аналогичный, что было бы большим и очень необходимым улучшением ИМХО.

...