我需要帮助将这个for循环转换为并行的forloop .
public void spellchecker()
{
Invoke(new MethodInvoker(delegate ()
{
using (Hunspell hunspell = new Hunspell("en_us.aff", "en_US.dic"))
{
foreach (Match match in Regex.Matches(GetRichTextBox().Text, @"\w+"))
{
string word = match.Value;
Font fnt = GetRichTextBox().Font;
Color color;
if (!hunspell.Spell(word))
{
fnt = new Font(fnt.FontFamily, fnt.Size, FontStyle.Underline);
color = Color.Red;
}
else
{
fnt = new Font(fnt.FontFamily, fnt.Size, FontStyle.Regular);
color = Color.Black;
}
GetRichTextBox().Select(match.Index, match.Length); // Selecting the matching word.
GetRichTextBox().SelectionColor = color;
GetRichTextBox().SelectionStart = GetRichTextBox().TextLength; // Resetting the selection.
GetRichTextBox().SelectionLength = 0;
}
}
}));
}
当我尝试实现并行for循环时,这是我的实现 . 我一直收到一条错误,说“ Arguments for method'Parallel.ForEach<TSource>(IEnumereable<TSourcce>,Action<TSource>
)'无法从使用中推断出来”
Parallel.ForEach(Regex.Matches(GetRichTextBox().Text, @"\w+"), match => {
string word = match.Value;
Font fnt = GetRichTextBox().Font;
Color color;
if (!hunspell.Spell(word))
{
fnt = new Font(fnt.FontFamily, fnt.Size, FontStyle.Underline);
color = Color.Red;
}
else
{
fnt = new Font(fnt.FontFamily, fnt.Size, FontStyle.Regular);
color = Color.Black;
}
GetRichTextBox().Select(match.Index, match.Length); // Selecting the matching word.
GetRichTextBox().SelectionColor = color;
GetRichTextBox().SelectionStart = GetRichTextBox().TextLength; // Resetting the selection.
GetRichTextBox().SelectionLength = 0;
});
1 回答
Parallel.ForEach()想要
IEnumerable<T>
作为它的第一个参数 . 必须从该类型参数推断TSource
,因为第二个参数是一个lambda表达式,其自身参数没有声明的类型 . Regex.Matches(string, string)返回MatchCollection
,它实现非泛型System.Collections.IEnumerable
,而不是IEnumerable<T>
. 它早于仿制药 . 所以编译器无法推断TSource
是什么 .但我们知道
TSource
应该是Match
. 所以使用Cast<T>()
:兴趣点
你可以明确地说lambda的参数是
Match
:而且你不会再得到类型推断错误 . 但是,您仍然会收到有关IEnumerable的错误,因为
MatchCollection
仍然不会实现泛型IEnumerable<T>
:顺便说一下,这就是为什么你不能在
foreach
的foreach
中使用var
而不明确地将循环变量声明为Match
或将其转换为循环体:基于编译器知道的所有内容,m
是object
.