Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 多线程翻译_C#_Multithreading - Fatal编程技术网

C# 多线程翻译

C# 多线程翻译,c#,multithreading,C#,Multithreading,下面的循环将英语单词“Welcome”翻译成其他几种语言 var result = ""; foreach (var toLanguage in OtherLanguages) { result += LanguageUtils.Translate("Welcome", English, toLanguage); } return result; LanguageUtils.Translate()是一个使用Microsoft Translator V2引擎的静态方法。到目前为止一切正

下面的循环将英语单词“Welcome”翻译成其他几种语言

var result = "";

foreach (var toLanguage in OtherLanguages)
{
   result += LanguageUtils.Translate("Welcome", English, toLanguage);
}

return result;
LanguageUtils.Translate()是一个使用Microsoft Translator V2引擎的静态方法。到目前为止一切正常。除了演出

我想知道是否可以通过在循环中使用多个线程来加快速度。因此,我不会像我一样翻译一种又一种语言,而是同时运行多个翻译

现在,我读了一些关于多线程的帖子和教程(例如),但老实说,我还是很困惑。这是我第一次处理多线程。。。也许是最后一次。所以我希望如果有经验的人能帮我写一些代码,告诉我如何将给定的代码片段转换成多线程方法


非常感谢

使用.NET 4.0,您可以执行以下操作:

更新:不要使用上述代码

代码不安全,因为
result.Append
在没有正确锁定的情况下修改
result
引用对象。另外,由于
Append
返回相同的StringBuilder引用,
Interlocked.CompareExchange
实际上不做任何事情,只是可能导致重复调用Append

上面的代码引入了一个巨大的性能瓶颈,因为
result.Append(txt)
需要在调用
CompareExchange
之前进行评估。因此,每次线程必须旋转时,它还必须再次计算
result.Append(txt)

@sehe建议的替代方案:

string.Join(", ", langs.AsParallel().Select(l => Translate("Welcome", English, l)));
ConcurrentBag结果=新的ConcurrentBag();
Parallel.ForEach(其他语言,toLanguage=>
{
结果.添加(LanguageUtils.Translate(“Welcome”,英语,toLanguage));
});

ConcurrentDictionary结果=新建ConcurrentDictionary();
Parallel.ForEach(其他语言,toLanguage=>
{
结果.TryAdd(toLanguage,LanguageUtils.Translate(“Welcome”,English,toLanguage));
});

使用.NET 4中提供的并行linq:

    return OtherLanguages.AsParallel()
                         .Select(toLanguage => LanguageUtils.Translate("Welcome", English, toLanguage));

在我自己的编辑和翻译字符串资源的免费工具()中,我提供了谷歌翻译(2011年12月停止)和微软必应翻译的两个接口

从我自己的经验以及用户对我的报道来看,当涉及到太多的请求和/或伪垃圾邮件检测时,必应相当挑剔

因此,我几乎假设您可以在代码中执行复杂的多线程构造,但仍然一无所获,因为您将收到“太多请求”和类似的异常


另一种方法是建立自己的查找数据库(内存或持久数据库,就像最适合您的要求一样),然后首先从数据库中查找后续翻译,如果在那里找不到,请转到Bing。

哇,伙计们。这是超快速的帮助。而且它非常简单,效果非常好(我已经尝试过你的建议)。谢谢你们所有人@sehe,Touché-代码示例更新。我没有使用
PLINQ
,因为我认为Ingmar需要一个返回
字符串而不是字符串序列的解决方案。所以
string.Join(“,”,langs.aspallel().Select(l=>Translate(“Welcome”,English,l))我担心
while
的性能会很糟糕。这里的关键是转换保证了并行化,但是聚合/累积结果根本不适合并行计算。这又是一次映射/还原,但是使用了一个简单的“还原”步骤,我认为
compareeexchange
毫无帮助,因为
StringBuilder.Append
。所有这一切都会造成
结果的不安全突变,发生的次数不可预测?@sehe,啊-在实际执行
比较交换
之前,它必须评估
结果。追加(txt)
调用。现在更有意义了:)为了让它工作,需要在调用之前计算
result.Append(txt)
,这样对它的引用就可以作为
CompareExchange
方法的值参数传递,这再次让我的代码示例更加有缺陷
ConcurrentBag<string> results = new ConcurrentBag<string>();
Parallel.ForEach(OtherLanguages,toLanguage =>
{
    results.Add(LanguageUtils.Translate("Welcome", English, toLanguage));
});
ConcurrentDictionary<string,string> results = new ConcurrentDictionary<string,string>();
Parallel.ForEach(OtherLanguages, toLanguage =>
{
    results.TryAdd(toLanguage, LanguageUtils.Translate("Welcome", English, toLanguage));
});
    return OtherLanguages.AsParallel()
                         .Select(toLanguage => LanguageUtils.Translate("Welcome", English, toLanguage));