38

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

Regex reg = new Regex(SomeRegexStringWith2Groups);
Parallel.ForEach<string>(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);
});
4

1 回答 1

37

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

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

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

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

于 2012-10-29T20:46:07.147 回答