简体   繁体   中英

Parallel For Not Working With EF4.1 and Automapper

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 get 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(), ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM