Powershell工作流并行语句共享变量

时间:2015-06-18 15:09:02

标签: powershell azure parallel-processing workflow

我很难理解为什么下面的代码表现如此。我在Google和StackOverflow中进行了大量搜索,无法找到任何似乎都能找到解决方案的内容。

在Azure自动化Runbook中,我试图在Parallel块中使用不同的参数运行相同的活动。我设法将问题细化到基本构建块,它也发生在没有涉及Azure的Powershell Workflow中。

当我在Powershell中执行此代码时,输​​出似乎被踩到并且随机性随之而来。这导致我的模块化工作流程活动严重不良。

如果我在并行块之外运行相同的代码段(有或没有序列块),它可以正常工作。 (您可以在下面的代码中看到注释掉的块。)

我注意到的另一件事是,如果我没有涉及第3个工作流程活动,则并行工作正常(如果它只是直接设置值而不是使用第3个工作流程中的输出值)。

但是,一旦Test调用TestChild调用TestGetLocationValue,并行块就会返回随机和意外的结果。

有人可以解释一下:

  1. 为什么会发生这种行为?
  2. 什么是允许其正常工作的变通方法/修复方法?
  3. 以下是几次运行的输出:

    运行一个     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'"
        #>
    }
    

0 个答案:

没有答案