多线程翻译

时间:2011-11-06 19:27:48

标签: c# multithreading

以下循环将英文单词“Welcome”翻译成其他几种语言。

var result = "";

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

return result;

LanguageUtils.Translate()是一种使用Microsoft Translator V2引擎的静态方法。到目前为止一切正常。除了表现。

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

现在,我阅读了一些关于MultiThreading的帖子和教程(例如http://www.albahari.com/threading/),但老实说,毕竟我很困惑。这是我第一次处理多线程......可能是最后一次。所以我希望有经验的人可以帮我解决一些代码,告诉我如何将我给定的代码片段转换为多线程方法。

非常感谢!

4 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:1)

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));
});

答案 2 :(得分:0)

使用.NET 4.0,您可以:

<子> <击>

<击>
volatile StringBuilder result = new StringBuilder();

void Magic()
{
    Parallel.ForEach(OtherLanguages, toLanguage =>
    {
        var resultIn = result;
        var txt = LanguageUtils.Translate("Welcome", English, toLanguage);

        do Thread.SpinWait(25);
        while (Interlocked.CompareExchange(ref result, result.Append(txt), resultIn) != result);
    });
}

<击>

更新:不要使用上面的代码

代码不是特定的,因为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)));

答案 3 :(得分:0)

在我自己的免费软件工具中编辑和翻译字符串资源(this one)我为Google Translate(截至2011年12月停用)和Microsoft Bing Translator提供了两种接口。

根据我自己的经验以及用户报告的内容,当涉及过多的请求和/或伪垃圾邮件检测时,Bing相当娇小。

所以我几乎可以假设您可以在代码中执行复杂的多线程构造,但仍然无法获得任何内容,因为您将收到“请求过多”等异常情况。

另一种方法可能是建立自己的查找数据库(内存中或持久性,最符合您的要求)并首先从数据库中查找后续翻译,如果在那里找不到,请转到秉。