private string trdoc(string str)
{
var listOfActions = new List<Action>();
string alltrdoc = "";
string doc = str;
var alldoc = doc.Split('\n');
foreach(string tt in alldoc)
{
//alltrdoc = alltrdoc + translate(tt) + '\n';//I can get the translated sentences in order but it's not multithread so it is slow.
listOfActions.Add(() => alltrdoc = alltrdoc + translate(tt) + '\n');//I can't get the translated sentences in order.
}
int paral = 4;
if (paral <= 0) { paral = 4; }
var options = new ParallelOptions { MaxDegreeOfParallelism = paral };
Parallel.Invoke(options, listOfActions.ToArray());
saveposcdic();
return alltrdoc;
}
translate(tt)
应生成翻译后的字符串。
我一直在努力翻译。我遇到了这个问题。
如果我使用没有,task或parallel.invoke的代码,那么我会以正确的顺序翻译文档。但是,如果我像上面那样运行parallel.invoke,我会把这些句子搞得搞乱。
如何使用task或parallel.invoke以正确的顺序获取翻译的文档?
我想在列表中添加带有数字的翻译句子,然后在完成所有任务后对列表进行排序,然后拆分句子并重新排列,但我认为必须有更好的方法。
以下代码有效但不平行。
private string trdoc(string str)
{
string alltrdoc = "";
string doc = str;
var alldoc = doc.Split('\n');
Task t = Task.Factory.StartNew(() => {
foreach (string tt in alldoc)
{
alltrdoc = alltrdoc + translate(tt) + '\n';
}
});
t.Wait();
saveposcdic();
return alltrdoc;
}
答案 0 :(得分:3)
原因是对的。你需要谨慎地处理并行性问题 你可以将它删除到linq。
var translatedStrings = alldoc
.AsParallel()
.WithDegreeOfParallelism(paral)
.AsOrdered()
.Select(tt => translate(tt));
var alltrdoc = string.Join("\n", translatedStrings);
这里有两个关键方法:
AsParallel
select
使trdoc
执行并行AsOrdered
,这将保持行的原始顺序。
您的第二个Parallel.Invoke
实施并不平行,因为您将所有工作放在一个任务中。这就像仅使用Action
{
"terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
"terminal.integrated.shellArgs.windows": ["-lic", "cd $OLDPWD; exec bash"],
}
一样
答案 1 :(得分:0)
我怀疑你没有在你的闭包中捕获循环变量。尝试将循环更改为:
foreach (string tt in alldoc)
{
string local_tt = tt;
listOfActions.Add(() => alltrdoc = alltrdoc + translate(local_tt) + '\n');
}
您遇到的另一个问题是您尝试使用多个线程更新alltrdoc
的单个值。它不会像那样工作。你真的应该考虑重构这段代码。
你最好像这样编写整个方法:
private string trdoc(string str)
{
return String.Join(Environment.NewLine, str.Split('\n').AsParallel().Select(x => translate(x)));
}
答案 2 :(得分:0)
private string trdoc(string str)
{
var alldoc = str.Split('\n');
string[] alltrdoc1 = new string[alldoc.Length];
Parallel.For(0, alldoc.Length,
index => {
alltrdoc1[index] = translate(alldoc[index]);
});
string alltrdoc = string.Join("\n", alltrdoc1);
saveposcdic();
return alltrdoc;
}
我已经使用了这段代码了。所有句子都以正确的顺序显示。我仍然不知道为什么Enigmativity的答案没有达到预期的效果。