Powershell版本:3.0
你好的脚本编写者。我有一个问题似乎无法找到答案。
要点: 尝试开始作业时,scriptblock参数将删除[System.Collections.Specialized.OrderedDictionary]的强制转换并将其替换为[Hashtable](即如果我不转换scriptblock的参数)。我的方案的一个例子如下:
$Job = Start-Job -ScriptBlock {
param(
[System.Collections.Specialized.OrderedDictionary]$Params = $(throw "Please pass Params.")
)
} -Name "Execute" -ErrorVariable Errors -ErrorAction Stop -ArgumentList $Params
当试图将OrderedDictionary对象传递给其中包含键/值对的作业时,它就像传递一个对象具有比预期的对象类型更多的属性:
$Params = [ordered]@{ "Param1" = "Value1"; "Param2" = "Value2" }
我正在使用以下行执行我的工作:
$ret = Receive-Job $job -Wait -AutoRemoveJob
结果:
错误:无法处理参数'Params'的参数转换。无法创建“System.Collections.Specialized.OrderedDictionary”类型的对象。未找到System.Collections.Specialized.OrderedDictionary对象的Param1属性。 可用的财产是: [Count],[IsReadOnly],[Keys],[Values],[IsFixedSize],[SyncRoot],[IsSynchronized]
注意:当没有传递键/值对时,强制转换仍然存在,并且对象很好地传递到scriptblock中(在参数列表中使用强制转换)。
任何人都可以详细说明确切原因或Start-Job cmdlet正在执行的操作吗?我只是错误地使用了这份工作吗?这种对象类型在作业中不可用吗?是因为它是一个系统对象吗?
答案 0 :(得分:0)
在你的Start-Job中使用脚本块对我来说似乎很奇怪。我不确定你为什么这样做,但是你给它的例子看起来应该有一个更好的方法来做到这一点。
我认为你的问题不在于你的工作,而是在构建OrderedDictionary。把它从这个工作中解脱出来,然后尝试按照你现在的方式制作那个对象并抛出错误。
至少您需要在@
之后插入[Ordered]
符号。
因为你似乎需要一些参数和所有参数,如果是我,我会将它移动到一个函数中,然后从$ret =
行调用函数,如下所示:
$Params = [ordered]@{ "Param1" = "Value1"; "Param2" = "Value2" }
Function Quibble {
param(
[System.Collections.Specialized.OrderedDictionary]$ParamIn = $(throw "Please pass Params.")
)
Start-Job -ScriptBlock {$ParamIn} -Name "Execute" -ErrorVariable Errors -ErrorAction Stop -ArgumentList $ParamIn
}
$ret = Receive-Job $(Quibble $Params) -Wait -AutoRemoveJob
虽然我实际上没有将真正的工作数据传递给它,但它基本上没有做任何事情。显然,如果没有其他任何东西改变我随机提出的愚蠢的函数名称,你将需要根据自己的需要对其进行修改。
答案 1 :(得分:0)
问题似乎是将[哈希表]转换为[System.Collections.Specialized.OrderedDictionary]的结果。
此代码表现出类似的行为:
$hashTable = @{ "Param1" = "Value1"; "Param2" = "Value2" }
[System.Collections.Specialized.OrderedDictionary]$dictionary = $hashTable
我只能推测,在Start-Job cmdlet中,您的[OrderedDictionary]会在传递给您的scriptblock之前被转换回[hashtable]。
无序字典会对你有用吗?使用[IDictionary]界面可以:
$Dictionary = [ordered]@{ "Param1" = "Value1"; "Param2" = "Value2" }
$job = Start-Job -Name "Execute" -ArgumentList $Dictionary -ScriptBlock {
param
(
<#
Using this interface type gives the following error:
Cannot process argument transformation on parameter 'Params'.
Cannot convert the "System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type "System.Collections.Specialized.IOrderedDictionary".
This would indicate that Start-Job is likely casting the [OrderedDictionary] back to a [hashtable].
[System.Collections.Specialized.IOrderedDictionary]
$Params = $(throw "Please pass Params.")
#>
# This type works but is unordered.
[System.Collections.IDictionary]
$Params = $(throw "Please pass Params.")
)
# Just to prove the params are passed in.
$Params | Out-String | Write-Host -ForegroundColor Green
}
$ret = Receive-Job $job -Wait -AutoRemoveJob