如何对Invoke-RestMethod进行并行处理以高效获取加密货币价格?
如何并行处理Invoke-RestMethod以获取加密货币价格?
我完全理解你现在的困扰——用串行foreach循环逐个请求Binance API,30多种加密货币的话,光等待每个请求响应就会浪费大量时间。下面给你几个实用的并行处理方案,你可以根据自己的PowerShell版本来选择:
方案1:PowerShell 7+ 推荐用 ForEach-Object -Parallel
这是最简洁高效的方式,PowerShell 7及以上版本内置了原生并行支持,不需要额外的作业管理逻辑:
$coins = @("XRP", "TRX", "VEN", "CND", "ICX", "XLM", "BNB") $base = "ETH" while ($true) { $coins | ForEach-Object -Parallel { # 引用外部作用域的base变量 $coin = $_ $base = $using:base $pair = $coin + $base $uri = "https://api.binance.com/api/v3/ticker/price?symbol=$pair" try { $priceData = Invoke-RestMethod -Method Get -URI $uri -ErrorAction Stop Write-Host "$coin/$base 当前价格: $($priceData.Price)" } catch { Write-Warning "获取 $coin 价格失败: $($_.Exception.Message)" } } -ThrottleLimit 10 # 控制并行请求数,避免触发API限流 Start-Sleep -Seconds 10 # 循环间隔,根据Binance API限制调整 }
关键说明:
-Parallel参数让每个币种的请求在独立运行空间同时执行-ThrottleLimit控制同时运行的任务数量,Binance公开API有请求频率限制,建议设为5-10之间$using:base用来引用并行块外部的变量,因为并行块有独立的作用域
方案2:PowerShell 5.x 兼容方案(用 Start-Job)
如果你还在使用PowerShell 5.x,可以用后台作业实现并行:
$coins = @("XRP", "TRX", "VEN", "CND", "ICX", "XLM", "BNB") $base = "ETH" while ($true) { # 批量启动后台作业 $jobs = $coins | ForEach-Object { Start-Job -ScriptBlock { $coin = $_ $base = $args[0] $pair = $coin + $base $uri = "https://api.binance.com/api/v3/ticker/price?symbol=$pair" try { $priceData = Invoke-RestMethod -Method Get -URI $uri -ErrorAction Stop return [PSCustomObject]@{ Coin = $coin Base = $base Price = $priceData.Price } } catch { return [PSCustomObject]@{ Coin = $coin Base = $base Price = "失败: $($_.Exception.Message)" } } } -ArgumentList $base } # 等待所有作业完成并获取结果 $results = $jobs | Wait-Job | Receive-Job # 清理后台作业,避免占用内存 $jobs | Remove-Job # 输出所有结果 foreach ($result in $results) { Write-Host "$($result.Coin)/$($result.Base) 价格: $($result.Price)" } Start-Sleep -Seconds 10 }
关键说明:
Start-Job创建后台独立进程处理每个请求Wait-Job等待所有作业完成,Receive-Job获取返回结果- 一定要用
Remove-Job清理作业资源,否则会持续占用系统内存
额外注意事项
- API限流:Binance公开API有请求频率限制(比如每分钟最多1200次请求),务必控制并行请求数量,避免被临时封禁
- 错误处理:添加
try/catch可以避免单个请求失败影响整个并行任务,还能记录错误细节 - 循环间隔:
while($true)循环里一定要加Start-Sleep,避免过于频繁的请求触发API防护机制
内容的提问来源于stack exchange,提问作者Tommy Gunz
相关产品推荐
相关产品推荐

