我试图在PowerShell中实现RAII式的资源管理。令我印象深刻的是在try-block中获取资源并在finally块中再次释放它(因为它保证了finally块的执行)。有时,我的资源相互依赖,所以我使用嵌套方法。大纲如下:
我的资源1是这样获得的(对于长度代码感到遗憾,找不到缩短它的方法):
function withResource1 {
param( [Parameter(Mandatory=$true)][scriptblock]$action )
try {
write-host "acquire resource1"
<# ... compute resource 1... #>
$resource1 = "<this is the resource>"
invoke-command -scriptBlock $action -args $resource1
} finally {
write-host "release resource1"
<# ... #>
}
}
资源2取决于1,所以我这样得到它:
function withResource2 {
param( [Parameter(Mandatory=$true)][scriptblock]$action )
withResource1 { param( $res1 )
try {
write-host "acquire resource2"
<# ... compute resource2, using resource1 ... #>
$resource2 = "<and this is the other resource>"
invoke-command -scriptBlock $action -args $resource2
} finally {
write-host "release resource2"
<# ... #>
}
}
}
现在(至少我在思考),我可以像这样使用资源2:
withResource2 { param( $res2 )
write-host "I'm happy to have '$res2', which depends on resource 1"
}
我预计输出为
acquire resource1
acquire resource2
I'm happy to have '<and this is the other resource>', which depends on resource 1
release resource2
release resource1
但实际发生的是某种无限循环。问题似乎是某种范围问题,因为如果我将action
重命名为ac
中的withResource2
,那么一切都按预期工作。
我怎样才能实现我想要的目标?是否有更好的方法在PowerShell中模拟RAII?
答案 0 :(得分:0)
好的,我发现了自己。
try
中的withResource2
块内,{0}范围内没有$action
变量,即
get-variable -name action -scope 0
找不到名为action
的变量。因此它会缩放到scope 1
,这是父作用域(withResource1
的范围),而$action
正好是我提供给withResource1
的脚本块。调用它会导致无限循环。
try
withResource2
中的$action
块实际上要调用的是withResource2
中的invoke-command
,其中 2 范围。因此,将withResource2
中的invoke-command -scriptBlock ( get-variable -name action -scope 2 ).Value -args $resource2
- 行更改为
{{1}}
诀窍。