多线程转换

本文关键字:转换 多线程 | 更新日期: 2023-09-27 18:13:35

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

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

languageutil . translate()是一个使用Microsoft Translator V2引擎的静态方法。到目前为止一切都很好。除了表演。

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

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

非常感谢!

多线程转换

在。net 4中使用parallel linq:

    return OtherLanguages.AsParallel()
                         .Select(toLanguage => LanguageUtils.Translate("Welcome", English, toLanguage));
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));
});

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

从我自己的经验和用户反馈来看,当涉及到过多的请求和/或伪垃圾邮件检测时,Bing是相当暴躁的。

所以我几乎假设你可以在你的代码中做复杂的多线程结构,仍然一无所获,因为你会收到"太多的请求"和类似的异常。

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

使用。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)));