1

I have a service that pulls emails for parsing. Each email is parsed by multiple visitors (all implementing a simple IEmailVisitor interface with one method: void Visit(VisitableEmail email). For some background context, visitor implementations include a SubjectVisitor, BodyVisitor, SummaryVisitor and so on.

The service has an IList<IEmailVisitor> which gets created once on startup, and then reused in a timer event in this manner:

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

The Email class has this method: public void Accept(IEmailVisitor visitor) { visitor.Visit(this);} As each visitor is visited, properties are set (or changed) on the email instance itself.

There can be quite a few emails to process. My question is, Would I be safe converting the above code to:

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

None of my visitors maintain state between invocations of Visit(this). I'm sure this question reflects my fairly superficial knowledge of task parallelism, but despite the reading I've been doing, I am unsure if this would be a safe approach (assuming there are enough emails each time to justify the operation).

4

2 回答 2

2

我的访问者都没有在调用 Visit(this) 之间保持状态

如果这是真的,那么它似乎是一个安全的操作。

如果此方法使用非线程安全的外部东西,则要么使其线程安全,要么不使用并行。

如果一次访问不会影响另一次访问,那么您可能最好并行处理。

于 2013-05-20T17:26:22.857 回答
0

我将把我自己的问题标记为已回答,因为从一些评论中可以清楚地看出,这个问题Parallel.ForEach()本身并没有那么多,而是围绕着你在考虑多线程时必须考虑的所有问题。TPL 当然提供了更简单的结构,但你仍然必须知道你在做什么。有时间再学习一些。

于 2013-05-21T15:11:21.287 回答