Powershell版本:3.0
各位编剧大家好。我有一个问题似乎找不到答案。
摘要:当尝试开始作业时,脚本块参数将删除[System.Collections.Specialized.OrderedDictionary]的强制转换,并将其替换为[Hashtable](也就是说,如果我不强制转换脚本块的参数)。我的场景示例如下:
$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.OrderderDictionary"的对象。找不到System.Collections.Specialized.OrderDiction对象的Param1属性。可用属性为:[Count]、[IsReadOnly]、[Keys]、[Values]、[IsFixedSize]、[SyncRoot]、[IsSynchronized]
注意:当不传递键/值对时,强制转换将保留,对象将很好地传递到脚本块中(在参数列表中强制转换)。
有人能详细说明确切的原因或Start-Job cmdlet正在做什么吗?我只是用错了工作吗?这个对象类型只是在作业中不可用吗?是因为它是一个系统对象吗?
在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
这对我来说没有错误,尽管我实际上并没有向它传递真正的工作数据,它基本上什么都没做。显然,如果没有其他东西改变我随机想出的愚蠢的函数名,你就需要根据自己的需要对其进行修改。
问题似乎是将[哈希表]转换为[System.Collections.Specialized.OrderedDictionary].的结果
此代码表现出类似的行为:
$hashTable = @{ "Param1" = "Value1"; "Param2" = "Value2" }
[System.Collections.Specialized.OrderedDictionary]$dictionary = $hashTable
我只能推测,在Start-Job cmdlet中,您的[OrderedDictionary]在传递到脚本块之前会被强制转换回[哈希表]。
一本无序的字典对你有用吗?使用[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