我很难理解为什么下面的代码表现如此。我在Google和StackOverflow中进行了大量搜索,无法找到任何似乎都能找到解决方案的内容。
在Azure自动化Runbook中,我试图在Parallel块中使用不同的参数运行相同的活动。我设法将问题细化到基本构建块,它也发生在没有涉及Azure的Powershell Workflow中。
当我在Powershell中执行此代码时,输出似乎被踩到并且随机性随之而来。这导致我的模块化工作流程活动严重不良。
如果我在并行块之外运行相同的代码段(有或没有序列块),它可以正常工作。 (您可以在下面的代码中看到注释掉的块。)
我注意到的另一件事是,如果我没有涉及第3个工作流程活动,则并行工作正常(如果它只是直接设置值而不是使用第3个工作流程中的输出值)。
但是,一旦Test调用TestChild调用TestGetLocationValue,并行块就会返回随机和意外的结果。
有人可以解释一下:
以下是几次运行的输出:
运行一个 PS U:>测试
Name Value
---- -----
Tag P4
Location {Hi, LP4, System.Collections.Hashtable}
Tag P5
Location Hi, LP5
Tag P6
Location Hi, LP6
运行两次 PS U:>测试
Name Value
---- -----
Tag P1
Location Hi, LP1
运行三 (使用详细信息,请注意" HashTable"引用)
PS U:\> Test -Verbose
VERBOSE: [localhost]:Parallel Run:
VERBOSE: [localhost]:[P2] Location before call: ''
VERBOSE: [localhost]:[P1] Location before call: ''
VERBOSE: [localhost]:[P4] Location before call: ''
VERBOSE: [localhost]:[P3] Location before call: ''
VERBOSE: [localhost]:[P5] Location before call: ''
VERBOSE: [localhost]:[P6] Location before call: ''
VERBOSE: [localhost]:[P7] Location before call: ''
VERBOSE: [localhost]:[P8] Location before call: ''
VERBOSE: [localhost]:[P9] Location before call: ''
VERBOSE: [localhost]:[P2] Location after call: 'Hi, LP2'
Name Value
---- -----
Tag P2
Location Hi, LP2
VERBOSE: [localhost]:[P3] Location after call: 'Hi, LP3'
VERBOSE: [localhost]:[P1] Location after call: 'Hi, LP1'
VERBOSE: [localhost]:[P4] Location after call: 'Hi, LP4 System.Collections.Hashtable'
VERBOSE: [localhost]:[P6] Location after call: 'Hi, LP6 System.Collections.Hashtable'
VERBOSE: [localhost]:[P5] Location after call: 'Hi, LP5 System.Collections.Hashtable'
VERBOSE: [localhost]:[P8] Location after call: 'Hi, LP8'
VERBOSE: [localhost]:[P7] Location after call: 'Hi, LP7'
VERBOSE: [localhost]:[P9] Location after call: 'Hi, LP9'
VERBOSE: [localhost]:[Test] Location Value After Parallel (Proves that Location doesn't leak to root workflow): ''
代码块(Test.ps1)
workflow TestGetLocationValue
{
param
(
$tag
)
$myLocation = "Hi, $tag"
Write-Output $myLocation
}
workflow TestChild
{
param
(
$tag
)
<#Write-Verbose "[$tag] MyLocation before call (Proves that mylocation doesn't leak to testchild workflow): '$myLocation'"#>
Write-Verbose "[$tag] Location before call: '$location'"
$location = TestGetLocationValue -tag "L$tag"
<# This works: $location = "Hi, $tag" #>
Write-Verbose "[$tag] Location after call: '$location'"
<#Write-Verbose "[$tag] MyLocation after call Value (Proves that mylocation doesn't leak to testchild workflow): '$myLocation'"#>
Write-Output @{
Tag = $tag
Location = $location
}
}
workflow Test
{
$location = $null
<#
Write-Verbose "Normal Run:"
TestChild -tag "N1"
TestChild -tag "N2"
TestChild -tag "N3"
TestChild -tag "N4"
TestChild -tag "N5"
TestChild -tag "N6"
TestChild -tag "N7"
TestChild -tag "N8"
TestChild -tag "N9"
Write-Verbose "[Test] Location Value After Normal (Proves that Location doesn't leak to root workflow): '$location'"
#>
Write-Verbose "Parallel Run:"
Parallel
{
TestChild -tag "P1"
TestChild -tag "P2"
TestChild -tag "P3"
TestChild -tag "P4"
TestChild -tag "P5"
TestChild -tag "P6"
TestChild -tag "P7"
TestChild -tag "P8"
TestChild -tag "P9"
}
Write-Verbose "[Test] Location Value After Parallel (Proves that Location doesn't leak to root workflow): '$location'"
<#
Write-Verbose "Sequence Run:"
Sequence
{
TestChild -tag "S1"
TestChild -tag "S2"
TestChild -tag "S3"
TestChild -tag "S4"
TestChild -tag "S5"
TestChild -tag "S6"
TestChild -tag "S7"
TestChild -tag "S8"
TestChild -tag "S9"
}
Write-Verbose "[Test] Location Value After Sequence (Proves that Location doesn't leak to root workflow): '$location'"
#>
}