在Parallel.ForEach循环中使用Regex.Matches时,我遇到了很多线程争用。我的理解是静态Regex类是线程安全的,但返回的匹配集合不是(MSDN)。在这个实现中,我认为返回收集的匹配'只是在它创建的单个线程中使用。我对静态类如何受到并行性影响的理解并不是很好,所以我很感激帮助!
Regex类本身是线程安全且不可变的(只读)。也就是说,可以在任何线程上创建Regex>对象并在线程之间共享;匹配>方法可以从任何线程调用,永远不会改变任何全局状态。
但是,Regex返回的结果对象(Match和MatchCollection)应该在单个线程上使用..
public ConcurrentBag<string> parseFile(string txtFile, List<string> regexPatterns)
{
ConcurrentBag<string> matchBag = new ConcurrentBag<string>();
using (StreamReader reader = new StreamReader(txtFile))
{
//loop through lines in parallel
Parallel.ForEach(File.ReadLines(txtFile), (line) =>
{
//loop through search patterns
foreach (string pattern in regexPatterns)
{
MatchCollection matches = Regex.Matches(line, pattern, RegexOptions.IgnoreCase); //LOTS OF CONTENTION HERE
foreach (var match in matches)
{
matchBag.Add(match.ToString());
}
}
});
}
return matchBag;
}
我还包含了探查器结果的屏幕截图,因此您可以具体了解争用发生的位置。 Contention Profiler Results