简体   繁体   English

多线程翻译

[英]Multi Threading Translations

The following loop translates the English word "Welcome" to a couple other languages. 以下循环将英语单词“ Welcome”翻译成其他两种语言。

var result = "";

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

return result;

LanguageUtils.Translate() is a static method that uses Microsoft Translator V2 engine. LanguageUtils.Translate()是使用Microsoft Translator V2引擎的静态方法。 Everything works fine so far. 到目前为止一切正常。 Except for the performance. 除了性能。

I was wondering if I could speed things up a little bit by using multiple threads inside my loop. 我想知道是否可以通过在循环中使用多个线程来加快速度。 So, instead of translating one language after another (as I do) I would run multiple translations at the same time. 因此,与其像我一样翻译另一种语言,不如我同时运行多种翻译。

Now, I read a couple post and tutorials about MultiThreading (eg http://www.albahari.com/threading/ ), but to be honest with you, I'm quite confused after all. 现在,我读了几篇有关MultiThreading的文章和教程(例如http://www.albahari.com/threading/ ),但是老实说,我毕竟很困惑。 That's the first time I was dealing with multi threading ... and probably the last time. 那是我第一次处理多线程……也许是最后一次。 So I was hoping if anybody experienced could help me out with some piece of code that shows me how to convert my given code snippet into a multi threading approach. 因此,我希望有经验的人可以帮助我完成一些代码,向我展示如何将给定的代码片段转换为多线程方法。

Thanks very much! 非常感谢!

use parallel linq as available in .NET 4: 使用.NET 4中可用的并行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));
});

or 要么

ConcurrentDictionary<string,string> results = new ConcurrentDictionary<string,string>();
Parallel.ForEach(OtherLanguages, toLanguage =>
{
    results.TryAdd(toLanguage, LanguageUtils.Translate("Welcome", English, toLanguage));
});

Using .NET 4.0 you can do: 使用.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); }); }
 
  

UPDATE: DON'T USE THE CODE ABOVE 更新:不要使用上面的代码

The code isn't treadsafe, as result.Append modifies the result reference object in-place without proper locking. 该代码是不treadsafe,如result.Append修改result就地参考对象没有适当的锁定。 Also, because Append returns the same StringBuilder reference, Interlocked.CompareExchange doesn't actually do anything, except perhaps cause the call to Append to be repeated. 另外,由于Append返回相同的StringBuilder引用,因此Interlocked.CompareExchange实际上不执行任何操作,除非可能导致对Append的调用重复。

The code above introduces a huge perfomance bottleneck, since result.Append(txt) needs to evaluate BEFORE CompareExchange can be called. 上面的代码引入了巨大的性能瓶颈,因为result.Append(txt)需要在CompareExchange之前进行评估。 So each time a Thread has to spin, it also has to evaluate result.Append(txt) again. 因此,每次线程旋转时,它也必须再次评估result.Append(txt)

An alternative suggested by @sehe: @sehe建议的替代方法:

string.Join(", ", langs.AsParallel().Select(l => Translate("Welcome", English, l)));

In my own freeware tool to edit and translate string resources ( this one ) I provide both interfaces to Google Translate (discontinued as of december 2011) and Microsoft Bing Translator. 在我自己的用于编辑和翻译字符串资源的免费软件工具( 工具)中,我提供了Google Translate(自2011年12月起停产)和Microsoft Bing Translator的两个接口。

From my own experiences as well as what users reported me, Bing is rather pettish when it comes to too much requests and/or pseudo spam detection. 根据我自己的经验以及用户的报告,当涉及到过多的请求和/或伪垃圾邮件检测时,Bing显得有些呆板。

So I pretty much assume that you can do complicated multi-threaded constructs in your code and still gain nothing since you will receive "too many requests" and the like exceptions then. 因此,我非常假设您可以在代码中执行复杂的多线程构造,但仍然一无所获,因为这样您将收到“请求过多”之类的异常。

An alternative approach could be to build up your own lookup database (in-memory or persistent, just as what fits best your requirements) and look up subsequent translations first from your database and if it is not found there, go over to Bing. 一种替代方法是建立自己的查找数据库(内存或持久性数据库,以最适合您的需求),然后先从数据库中查找后续翻译,如果找不到,请转到Bing。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM