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;
}
最佳答案
神秘主义是对的。您需要谨慎处理并行性。
您可以将其委托(delegate)给 linq。
var translatedStrings = alldoc
.AsParallel()
.WithDegreeOfParallelism(paral)
.AsOrdered()
.Select(tt => translate(tt));
var alltrdoc = string.Join("\n", translatedStrings);
这里有两个关键方法:
AsParallel
这使得 select
并行执行并且 AsOrdered
这将保持原始的行顺序。
您的第二个 trdoc
实现不是并行的,因为您将所有工作放在一个任务中。这就像运行 Parallel.Invoke
只有一个 Action
关于c# - 如何使用任务或并行调用以正确的顺序获得翻译结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46066428/