c# - 如何使用任务或并行调用以正确的顺序获得翻译结果?

标签 c# multithreading parallel-processing

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/

相关文章:

mpi - 杀死MPI进程

c# - 有没有办法确定我在 foreach 循环中的哪一行?

c# - 为什么不首先调用基类构造函数

c++ - 在固定数量的线程之间划分数组

c# - 处理后监控多个 Threading.Timers

c++ - 用于 visual studio express 2010 的 PThreads

matlab - 无法使用 MATLAB MapReducer 2014b 中的 'local' 配置文件启动并行池

c# - 自定义控件和工具箱选项卡

c# - DirectoryEntry CommitChanges() 未提交更改?

java - 线程并发——使用字符串对象的锁进行同步