0

我有一个字符串列表,如果我按顺序使用 NHunspell 运行拼写检查,那么一切正常;但是如果我对 List 使用 Parallel.For 循环,应用程序会在中间停止工作(一些地址违规错误)

public static bool IsSpellingRight(string inputword, byte[] frDic, byte[] frAff, byte[] enDic, byte[] enAff)
{
    if (inputword.Length != 0)
    {
        bool correct;
        if (IsEnglish(inputword))
        {
            using (var hunspell = new Hunspell(enAff, enDic))
            {
                correct = hunspell.Spell(inputword);
            }
        }
        else
        {
            using (var hunspell = new Hunspell(frAff, frDic))
            {
                correct = hunspell.Spell(inputword);
            }
        }
        return correct ;
    }

    return false;
}

编辑:

var tokenSource = new CancellationTokenSource();
CancellationToken ct = tokenSource.Token;

var poptions = new ParallelOptions();

// Keep one core/CPU free...
poptions.MaxDegreeOfParallelism = Environment.ProcessorCount - 1;
Task task = Task.Factory.StartNew(delegate
{
    Parallel.For(0, total, poptions, i =>
    {
        if (words[i] != "")
        {
            _totalWords++;

            if (IsSpellingRight(words[i],dictFileBytes,
                affFileBytes,dictFileBytesE,affFileBytesE))
            {
                // do something   

            }
            else
            {
                BeginInvoke((Action) (() =>
                {
                    //do something on UI thread
                }));
            }
        }
    });
}, tokenSource.Token);

task.ContinueWith((t) => BeginInvoke((Action) (() =>
{
    MessaageBox.Show("Done");
})));
4

2 回答 2

1

好的,现在我可以看到一个潜在的问题。排队

_totalWords++;

你正在增加一个值,那个(我想)是在循环之外的某个地方声明的。使用锁定机制。

编辑:另外,您可以使用Interlocked.Increment(ref val);比简单锁定更快的方法。

edit2:这是我在评论中描述的锁定对于您遇到的问题的外观:

static object Locker = new object();    //anywhere in the class

//then in your method
if (inputword.Length != 0)
{
   bool correct;
   bool isEnglish;
   lock(Locker) {isEnglish = IsEnglish(inputword);}
   if(isEnglish)
   {
       //..do your stuff
   }
    //rest of your function
}
于 2013-08-17T20:26:41.060 回答
1

我认为你应该忘记你的并行循环实现正确的事情。

您是否知道此代码加载并构建字典的事实:

    using (var hunspell = new Hunspell(enAff, enDic))
    {
        correct = hunspell.Spell(inputword);
    }

您正在使用代码一遍又一遍地加载和构建字典。这太慢了!加载您的字典一次并检查所有单词,然后将其丢弃。并且不要并行执行此操作,因为 Hunspell 对象不是线程安全的。

伪代码:

Hunspell hunspell = null;
try
{
    hunspell = new Hunspell(enAff, enDic)

    for( ... )
    {
      hunspell.Spell(inputword[i]);
    }
    }
}
finally
{
    if( hunspell != null ) hunspell.Dispose();
}

如果您需要并行检查大量单词,请考虑阅读这篇文章: http: //www.codeproject.com/Articles/43769/Spell-Check-Hyphenation-and-Thesaurus-for-NET-with

于 2013-08-20T07:38:03.720 回答