1

解析のためにメールをプルするサービスがあります。各電子メールは複数の訪問者によって解析されます (すべてIEmailVisitorが 1 つのメソッドを持つ単純なインターフェースを実装していvoid Visit(VisitableEmail email)ます:

サービスには、IList<IEmailVisitor>起動時に一度作成され、次の方法でタイマー イベントで再利用される があります。

foreach (var email in emailsToParse)
{
    foreach (var visitor in _visitors)
    {
        email.Accept(visitor);
    }
}

Email クラスには次のメソッドがあります。public void Accept(IEmailVisitor visitor) { visitor.Visit(this);}各訪問者が訪問されると、電子メール インスタンス自体のプロパティが設定 (または変更) されます。

処理する電子メールがかなりの数になる可能性があります。私の質問は、上記のコードを次のように安全に変換できるかどうかです。

Parallel.ForEach(emailsToParse, email =>
{
    foreach (var visitor in _visitors)
        email.Accept(visitor);
});

の呼び出し間で状態を維持する訪問者はいませんVisit(this)。この質問は、タスクの並列処理に関する私のかなり表面的な知識を反映していると確信していますが、私が行ってきた読書にもかかわらず、これが安全なアプローチであるかどうかはわかりません (操作を正当化するのに十分な電子メールが毎回あると仮定して)。

4

2 に答える 2

2

Visit(this) の呼び出し間で状態を維持する訪問者はいません

これが本当なら、安全な操作だと思われます。

このメソッドがスレッドセーフではない外部のものを使用する場合は、スレッドセーフにするか、並列を使用しないでください。

1 回の訪問が別の訪問に影響を与えない場合は、おそらく並行して行ってもよいでしょう。

于 2013-05-20T17:26:22.857 に答える