I'm having problems with implementing a Parallel For it seems to cause error messages intermittently.
I am trying to speed up the process of mapping a complex ViewModel that is built using lots of navigation proprieties etc. The code below is a simplified non parallel version.
var Model = MyRepository.All.AsEnumerable().Select(a => Mapper.Map<Model, ViewModel>(a));
return View(Model);
This works fine and I never get any errors. Knowing that my ViewModel mapping was complex I decided to test a parallel version to see if it was faster. Simplified version is:
var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount};
ConcurrentBag<ViewModel> ViewModel = new ConcurrentBag<ViewModel>();
Parallel.ForEach(Model, options, dr => ViewModel.Add(Mapper.Map<Model,ViewModel>(dr)));
var ViewModelSorted = ViewModel.AsEnumerable().OrderBy(a => a.SortDate);
return View(ViewModelSorted);
It often completes and displays results in half the time. So it is clearly faster. However I now sometimes ge开发者_如何转开发t error messages about null reference exceptions etc in some of my partial entity class methods. These errors seem intermittent even when I test the same data. I don't really understand why? The code doesn't change or update DB etc and nothing else is updating the DB while I run the code. Is it just not possible to use a Parallel For in this situation?
Update my error message is :
{"Object reference not set to an instance of an object."}
Stack trace:
at SpotList.Domain.Entities.Vessel.GetNextFixture(fixture fixture) in C:\Users\Graeme\documents\visual studio 2010\Projects\SpotList\Domain\Entities\Vessel.cs:line 47
at SpotList.WebUI.Infrastructure.AutoMap.Charterer2.ResolveCore(Vessel source) in C:\Users\Graeme\documents\visual studio 2010\Projects\SpotList\SpotList\Infrastructure\AutoMap\AutoMapperBootstrapper.cs:line 401
at AutoMapper.ValueResolver`2.Resolve(ResolutionResult source)
at AutoMapper.DeferredInstantiatedResolver.Resolve(ResolutionResult source)
at AutoMapper.PropertyMap.ResolveValue(ResolutionContext context)
at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.MapPropertyValue(ResolutionContext context, IMappingEngineRunner mapper, Object mappedObject, PropertyMap propertyMap)
The error line corresponds to the code here:
public fixture GetNextFixture(fixture fixture)
{
fixtureperiod fixtureperiod = fixture.GetMostRecentFixturePeriod();
So fixture is null however the same thing never seems to occur if I run the non-parallel version
Thanks
Graeme
Your Model appears to be a lazily-evaluated structure, relying on the Entity Framework context. Entity Framework contexts are not thread-safe. Try pulling all the data from the context in a non-parallel operation, and then take care of the mapping as a parallel operation.
Parallel.ForEach(Model.ToList(), ...
精彩评论