powershell - 我的 Powershell 脚本不做多线程工作,为什么?
问题描述
#my script 是https://www.codeproject.com/Tips/895840/Multi-Threaded-PowerShell-Cookbook的摘录 #the first example #the issue is where ".AddScript($secb)" is. 所有的工作都是按顺序完成的,谁能解释一下???#为什么在我的脚本中,.AddScript($sb) 是并发的?
$numThreads = 5
# Create session state
$myString = "this is session state!"
$sessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
$sessionstate.Variables.Add((New-Object -TypeName System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList "myString" ,$myString, "example string"))
# Create runspace pool consisting of $numThreads runspaces
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, 5, $sessionState, $Host)
$RunspacePool.Open()
$Jobs = @()
$sb={
param ($data)
$r=Get-Random
Write-Host "before $r"
Start-Sleep -Seconds 3
Write-Host "after $r"
}
$secb={
param ($block)
Invoke-Command -ScriptBlock $block
}
1..5 | % {
#below line is not concurrent , i don't know why
$Job = [powershell]::Create().AddScript($secb) # $Job = [powershell]::Create().AddScript($sb) could do multi-thread
$Job.AddArgument($sb)
$Job.RunspacePool = $RunspacePool
$Jobs += New-Object PSObject -Property @{
RunNum = $_
Job = $Job
Result = $Job.BeginInvoke()
}
}
Write-Host "Waiting.." -NoNewline
Do {
Write-Host "." -NoNewline
Start-Sleep -Seconds 1
} While ( $Jobs.Result.IsCompleted -contains $false) #Jobs.Result is a collection
解决方案
到目前为止,我还不是专家RunSpaces
,通常每当我需要多线程时,我都会使用该ThreadJob
模块。我不确定您在代码中做错了什么,但我可以向您展示您正在尝试做的工作示例。我从这个答案(感谢 Mathias)中拿了这个例子,这个例子非常好,并做了一些修改。
代码:
cls
$elapsedTime = [System.Diagnostics.Stopwatch]::StartNew()
$numThreads = 5
# Create session state
$myString = "this is session state!"
$sessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
$sessionstate.Variables.Add((New-Object -TypeName System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList "myString" ,$myString, "example string"))
# Create runspace pool consisting of $numThreads runspaces
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, 5, $sessionState, $Host)
$RunspacePool.Open()
$runspaces = foreach($i in 1..5)
{
$PSInstance = [powershell]::Create().AddScript({
param ($TestNumber)
Write-Output "Test Number: $TestNumber"
$r={Get-Random}
Write-Output "before $(& $r)"
Start-Sleep -Seconds 3
Write-Output "after $(& $r)"
}).AddParameter('TestNumber',$i)
$PSInstance.RunspacePool = $RunspacePool
[pscustomobject]@{
Instance = $PSInstance
Result = $PSInstance.BeginInvoke()
}
}
while($runspaces|Where-Object{-not $_.Result.IsCompleted})
{
Start-Sleep -Milliseconds 500
}
$resultRunspace = [collections.generic.list[string]]::new()
$Runspaces|ForEach-Object {
$resultRunspace.Add($_.Instance.EndInvoke($_.Result))
}
$elapsedTime.Stop()
"Elapsed Time: {0}" -f $elapsedTime.Elapsed.TotalSeconds
""
$resultRunspace
结果:
Elapsed Time: 3.1271587
Test Number: 1 before 474010429 after 2055432874
Test Number: 2 before 1639634857 after 1049683678
Test Number: 3 before 72786850 after 2046654322
Test Number: 4 before 1958738687 after 1832326064
Test Number: 5 before 1944958392 after 1652518661
现在,再次,如果您能够安装模块,我会推荐ThreadJob
它,因为它更易于使用并且执行速度与RunSpaces
.
前段时间我写了一个脚本,它将遍历所有目录$HOME
并获取每个目录的文件数,该脚本旨在比较Linear Loops
vs ThreadJob
vsRunSpace
这里的结果以及为什么我总是推荐ThreadJob
推荐阅读
- sql - 如何在满足条件的行的时间段内选择带有时间戳的行
- javascript - React Hook UseState 调用后不设置值
- node.js - 如何在 GOT http 请求中设置间隔?
- python - 以与 pyspark 类似的方式在 pandas 中分配一个新列
- c# - 如何在 osr 自定义浏览器中正确设置键盘事件
- r - 在 readRDS(nsInfoFilePath) 中:读取文件时出错
- amazon-web-services - AWS data pipeline get data from hive to s3
- botframework - 如果机器人连续 3 次尝试都无法回答,则显示消息“连接到客户服务”...dotnet core 3.1................MS Bot Framework
- c# - 开始了第二次操作……(但没有并行访问)
- firebase - 如何取消 Flutter 实时数据库事务