Vaze
Vaze

Reputation: 144

When is the work of a C# Parallel.ForEach done?

I'm developing an MVC4 website in C#. The following code should fill a ConcurrentBag (DisplayModels) with items before passing everything to the view.

    Parallel.ForEach(model.Products, p =>
    {
        model.DisplayModels.Add(new DisplayBoardModel()
        {
            Market = model.Market,
            Product = p
        });
    });

    return View(model);

I'm finding that on any given execution DisplayModels appears to be filled to a different point. As if the ForEach is completing before each background task has returned.

My understanding of the Parallel.ForEach was that it processed each item in parallel but still blocked the calling thread until all of it's work was done. Is this not correct?

Is there something else I should be doing to stop the action returning before the model is ready? Using a normal foreach worked fine

Upvotes: 2

Views: 650

Answers (1)

Henk Holterman
Henk Holterman

Reputation: 273264

The Parallel.ForEach() works fine, and completes all at once as expected.

But your model.DisplayModels.Add() probably isn't thread-safe. What collection are you using?

You could fix this by a) using a Concurrent collection for DisplayModels or b) turn the ForEach into a PLINQ query. But unless DisplayBoardModel() does some heavy CPU work (and a ctor usually doesn't) there is little point in making this parallel.

So, just use a simple foreach()


Edit, new information

each DisplayBoardModel make a database request

So this is a potential cause. Does every Db operation create its own Connection (Context)? Any chance that an exception is silently ignored?

Upvotes: 5

Related Questions