Reputation: 144
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
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()
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