我想知道如何在管道停止时正确释放脚本化 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
块或类似块,恕我直言,这将是一个伟大且急需的改进。