对于C#中的匹配,Regex实例线程是否安全?

我有这个正则表达式,我在Parallel.ForEach 。 安全吗?

 Regex reg = new Regex(SomeRegexStringWith2Groups); Parallel.ForEach(MyStrings.ToArray(), (str) => { foreach (Match match in reg.Matches(str)) //is this safe? lock (dict) if (!dict.ContainsKey(match.Groups[1].Value)) dict.Add(match.Groups[1].Value, match.Groups[2].Value); }); 

Regex对象是只读的,因此是线程安全的。 这是他们的回报, Match对象可能会导致问题。 MSDN证实了这一点 :

Regex类本身是线程安全且不可变的(只读)。 也就是说,可以在任何线程上创建Regex对象并在线程之间共享; 匹配方法可以从任何线程调用,永远不会改变任何全局状态。

但是, Regex返回的结果对象(Match和MatchCollection)应该在单个线程上使用。

我会担心你的Match集合是如何以可能并发的方式生成的,这可能会导致集合行为有点奇怪。 一些Match实现使用延迟评估,这可能会导致foreach循环中的一些疯狂行为。 我可能会收集所有的匹配,然后在以后评估它们,既安全又能获得一致的性能。