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 によって返される結果オブジェクト (Match および MatchCollection) は、単一のスレッドで使用する必要があります。

あなたの Match コレクションがどのように並行して生成されているかが気になります。これにより、コレクションが奇妙な動作をする可能性があります。一部の Match 実装では遅延評価が使用されるため、そのforeachループで異常な動作が発生する可能性があります。おそらく、すべてのマッチを収集し、後で評価して、安全性と一貫したパフォーマンスの両方を得るでしょう。

于 2012-10-29T20:46:07.147 に答える