如何解决在 Powershell 中正确使用 ForEach -parallel?
我想处理大量 URL 并获取 *.jpg 文件位置。
问题是第二个 foreach 中的 $entry
不是线程安全的。
该脚本引发了数百个错误,因为 $entry
被一遍又一遍地覆盖。
当我将内部 foreach
移到 ForEach-Object
之外时,它工作正常但速度很慢。
如何在我的 ForEach-Object
中正确处理拆分输出而不会出现这些错误?
-
$array
只包含大量网址 -
$clean_img_array
是操作的输出数组 -
$tmpArray
是对$clean_img_array
的引用,以便在并行 ForEach 中使用它
错误:
InvalidOperation:
Line |
14 | [void]$tmpArray:clean_img_array.Add($entry);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| You cannot call a method on a null-valued expression.
片段:
$clean_img_array = [System.Collections.ArrayList]@();
$array | ForEach-Object -Parallel {
$web = Invoke-RestMethod $_;
$i=1;
foreach($entry in $web.Split("`"")){
echo $entry;
if($entry.IndexOf(".jpg") -ne -1 -And $entry.IndexOf("http") -ne -1){
if($entry.IndexOf("?") -ne -1){
$tmpArray = $using:clean_img_array;
[void]$tmpArray.Add($entry.Substring(0,$entry.IndexOf('?')));
}else{
$tmpArray = $using:Clean_img_array;
[void]$tmpArray:clean_img_array.Add($entry);
}
}
}
} -ThrottleLimit 20
解决方法
这是一个简单的例子。 $a 和 $b 都是数组。 $b 是并行循环的结果。就像文档中的 example 12。
$a = 1..10
$b = $a | foreach-object -parallel { $_ + 1 }
$b
2
3
4
5
6
7
8
9
10
11
,
感谢支持!
我将@js2012 的答案与我自己的答案结合起来。
仅返回并不能解决 $entry
的线程取消保存行为,但清楚地解开了工作流程。
但是我使用了内联版本的 .foreach
和管道变量 $_
在我看来是线程安全的。现在运行速度非常快,超过 200 万个条目。
-
$array
保存要处理的网址 -
$clean_img_array
返回抓取的图片网址$clean_img_array = $array | ForEach-Object -Parallel { $web = Invoke-RestMethod $_; $web.Split("`"").foreach({ if($_ -ne $null){ if($_.IndexOf(".jpg") -ne -1 -And $_.IndexOf("http") -ne -1){ if($_.IndexOf("?") -ne -1){ return $_.Substring(0,$entry.IndexOf('?')); }else{ return $_; } } } }); } -ThrottleLimit 25
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。