C# 如何使用任务或并行调用以正确的顺序获得转换结果?
我怀疑您没有捕获闭包中的循环变量。尝试将循环更改为如下所示:C# 如何使用任务或并行调用以正确的顺序获得转换结果?,c#,multithreading,parallel-processing,C#,Multithreading,Parallel Processing,我怀疑您没有捕获闭包中的循环变量。尝试将循环更改为如下所示: 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 = alltrd
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;
}
foreach (string tt in alldoc)
{
string local_tt = tt;
listOfActions.Add(() => alltrdoc = alltrdoc + translate(local_tt) + '\n');
}
另一个问题是,您试图使用多个线程更新alltrdoc
的单个值。它不会那样工作的。你真的应该考虑重构这个代码。
您最好这样编写整个方法:
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;
}
foreach (string tt in alldoc)
{
string local_tt = tt;
listOfActions.Add(() => alltrdoc = alltrdoc + translate(local_tt) + '\n');
}
神秘性是正确的。您需要谨慎地处理并行问题。
你可以把它委托给林克
private string trdoc(string str)
{
return String.Join(Environment.NewLine, str.Split('\n').AsParallel().Select(x => translate(x)));
}
这里有两个关键方法:它使
select
并行执行,并将保持行的原始顺序
您的第二个trdoc
实现不是并行的,因为您将所有工作放在一个任务中。这就像并行运行一样。只需一个操作
var translatedStrings = alldoc
.AsParallel()
.WithDegreeOfParallelism(paral)
.AsOrdered()
.Select(tt => translate(tt));
var alltrdoc = string.Join("\n", translatedStrings);
我已经用这个代码工作了。所有的句子都按正确的顺序排列。我仍然不知道为什么Enigmativity的答案没有达到预期效果。如果原始行在一个数组中,您可以创建一个结果数组,让任务将结果放在您获得结果的位置。或者可能是并行的。因为
也会起作用,使它变得更容易?我不知道为什么,但它仍然以错误的顺序给出翻译的句子。仍在试图找出原因。@user1785594-您是否尝试过我替换您的trdoc
方法?是的。两个都是,但都没用。我不知道为什么。@user1785594-调用translate
需要多长时间?代码是线程安全的吗?你能发布代码吗?它在mega链接的zip文件中包含的form1.cs中。这个计划本身还远远没有完成。它使用nuget包mecab进行日语词性标记。我忘记了.AsOrdered()
。