我想知道当管道停止时如何正确地将对象放置在脚本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的,未经编译。)
答案 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
块或类似的块,恕我直言,这是一个很大且非常需要的改进。