使用Powershell工作流程时,如何在Inlinescript块中包含线程安全实例变量?

时间:2013-07-17 16:08:18

标签: powershell-v3.0

我正在使用PowerShell 3并使用Workflows,我遇到了一些奇怪的事情。 我正在使用 inlinescript 块来保存一些代码来表示我想要运行多个实例的任务。我发现可以跨并行实例访问在 inlinescript 块中声明的变量。

此处的示例具有并行进程休眠一个随机数毫秒,但您可以从控制台输出中看到多个并发进程可以睡眠相同的毫秒数。当然,这是可能的,但它经常是很明显,数据不是线程安全的。

workflow Invoke-ForEachParallel
{
    param([string[]]$Computers)
    foreach -parallel($PC in $Computers)
    {
        inlinescript {
            "Executing on $using:PC"
            [int]$i = get-random -min 200 -max 3000
            "`t$using:PC - Sleeping for $i milliseconds."
            start-sleep -Milliseconds $i
            "`tFinished processing on $using:PC"
        }
    }
}  

cls
Invoke-ForEachParallel (1..50)

所以,问题是:我怎样才能确保每个并发进程都使用自己的变量实例?

1 个答案:

答案 0 :(得分:0)

David Wyatt在这个主题上简单而详细地回答了这两个问题。 http://social.technet.microsoft.com/Forums/scriptcenter/en-US/155b5638-5477-4e7c-a154-c6b56f6c3145/how-can-i-have-threadsafe-instance-variables-within-inlinescript-block-when-using-powershell?prof=required

简单回答: 当您使用inlineScript时,它不是一个多线程场景;这是多过程。 Workflow Foundation启动一个新的powershell.exe进程,每次都执行inlineScript块中的代码(您可以在运行脚本时在任务管理器中看到这种情况)。没有办法在不同的进程之间存在线程安全问题(除非您有正确的调试程序并且出于某些愚蠢的原因使用WriteProcessMemory)。

编辑:在我的Windows 7系统上,此脚本中生成的PowerShell.exe进程的数量似乎限制为5.我不确定WF是否会在每次执行inlineScript块时拆除并重新启动这些进程,或者,如果它将它们视为一个池,重复使用它们直到完成所有操作。出于性能原因,我会假设后者,但我没有阅读任何MS文档。