2017-10-19 60 views
0

我目前正在使用NHunspell在WPF中实现自定义拼写检查,因为.Net框架的本地解决方案并不适合我的需求。但是我在检查大文本中的单词时遇到了麻烦,例如带有10个段落的Lorem Ipsum,因为我需要检查每个单词,看它是否包含在Hunspell使用的字典中,如果不是,我需要强调Word。如何验证RichTextBox中的大文本而不冻结屏幕?

我有这种当前的方法,它每次检查KeyUp是一个Backspace或空格键的所有文本。

var textRange = new TextRange(SpellCheckRichTextBox.Document.ContentStart, 
SpellCheckRichTextBox.Document.ContentEnd); 
     textRange.ApplyPropertyValue(Inline.TextDecorationsProperty, null); 
     _viewModel.Text = textRange.Text; 
     var zzz = _viewModel.Text.Split(' '); 
     var kfeofe = zzz.Where(x => _viewModel.MisspelledWords.Contains(x)); 
     foreach (var item in kfeofe) 
     { 
      TextPointer current = textRange.Start.GetInsertionPosition(LogicalDirection.Forward); 

      while (current != null) 
      { 
       string textInRun = current.GetTextInRun(LogicalDirection.Forward); 
       if (!string.IsNullOrWhiteSpace(textInRun)) 
       { 
        int index = textInRun.IndexOf(item.ToString()); 
        if (index != -1) 
        { 
         TextPointer selectionStart = current.GetPositionAtOffset(index, LogicalDirection.Forward); 
         TextPointer selectionEnd = selectionStart.GetPositionAtOffset(item.ToString().Length, LogicalDirection.Forward); 
         TextRange selection = new TextRange(selectionStart, selectionEnd); 

         selection.ApplyPropertyValue(Inline.TextDecorationsProperty, TextDecorations.Underline); 
        } 
       } 
       current = current.GetNextContextPosition(LogicalDirection.Forward); 
      } 

     } 

不过,我想我需要一个异步的解决方案,所以它不会阻止我的主线程和用户的打字。 - 理论上我在考虑如果用户花费了2秒以上的时间没有键入,然后将选中的TextRange返回到我的RichTextBox(SpellCheckRichTextBox),那么我正在考虑运行并行线程。

有人可以提出任何解决方案,这样在处理大文本时我可以减少验证速度?我真的卡住了,任何帮助,将不胜感激。 在此先感谢!

回答

1

第一个改进是

zzz.AsParallel().Where(x => _viewModel.MisspelledWords.Contains(x)).ToList(); 

这显然假定您.MisspelledWords.Contains(x)的东西,可以并行进行。它可能已经是ConcurrentDictionary

一个拼写错误的词集合的事实,让我相信你已经解析文本一次。那么为什么要解析它两次?你为什么不能把这些通过?这将是另一种可能的优化。

是的,当用户停止输入时,在另一个线程中完成所有这些操作将会更好。