patterncsharpModerate
Simple parallel foreach loop code correctness
Viewed 0 times
simpleloopcorrectnesscodeparallelforeach
Problem
I have both the regular for each loop and its equivalent paralleled version. The loop simply iterates through a collection, looking for the rate key in a local
Is the paralleled code correct and has the lock been placed correctly?
db instance and then updating the topic code.using (var db = new SomeEntities())
{
foreach (var measure in measures)
{
var keytofind= measure.RateKey.ToString(CultureInfo.InvariantCulture);
var firstOrDefault = db.RatesMappings.FirstOrDefault(r => r.RateKey == keytofind);
if (firstOrDefault != null)
measure.TopicCode = firstOrDefault.TopicCode;
}
Parallel.ForEach(measures, measure=>
{
var keytofind= rawDataMeasure.RateKey.ToString(CultureInfo.InvariantCulture);
lock(measure)
{
var firstOrDefault = db.RatesMappings.FirstOrDefault(r => r.RateKey == keytofind);
if (firstOrDefault != null)
measure.TopicCode = firstOrDefault.TopicCode;
}
});
}Is the paralleled code correct and has the lock been placed correctly?
Solution
No, when you use the lock like that, it's completely useless. Each lock would get its own identifier, so none of he locks would keep any other thread out. To make the lock work at all, you need to use the same identifier for all locks. Demonstration:
However, if you need a lock around the code in a parallel loop, then the parallel loop is pointless. The reason that you use the parallel loop is that several threads can run at once, and the lock would prevent that.
object sync = new Object();
var keytofind = rawDataMeasure.RateKey.ToString(CultureInfo.InvariantCulture);
Parallel.ForEach(measures, measure => {
lock(sync) {
var firstOrDefault = db.RatesMappings.FirstOrDefault(r => r.RateKey == keytofind);
if (firstOrDefault != null) {
measure.TopicCode = firstOrDefault.TopicCode;
}
}
});However, if you need a lock around the code in a parallel loop, then the parallel loop is pointless. The reason that you use the parallel loop is that several threads can run at once, and the lock would prevent that.
Code Snippets
object sync = new Object();
var keytofind = rawDataMeasure.RateKey.ToString(CultureInfo.InvariantCulture);
Parallel.ForEach(measures, measure => {
lock(sync) {
var firstOrDefault = db.RatesMappings.FirstOrDefault(r => r.RateKey == keytofind);
if (firstOrDefault != null) {
measure.TopicCode = firstOrDefault.TopicCode;
}
}
});Context
StackExchange Code Review Q#51665, answer score: 10
Revisions (0)
No revisions yet.