并行不使用EF4.1和Automapper

时间:2011-06-23 16:31:37

标签: c# entity-framework c#-4.0 automapper parallel-processing

我遇到了实现并行的问题因为它似乎间歇性地导致错误消息。

我正在尝试加快映射使用大量导航属性等构建的复杂ViewModel的过程。下面的代码是简化的非并行版本。

var Model = MyRepository.All.AsEnumerable().Select(a => Mapper.Map<Model, ViewModel>(a));     
return View(Model);

这很好用,我从来没有得到任何错误。知道我的ViewModel映射很复杂,我决定测试并行版本以查看它是否更快。简化版本是:

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);

它通常会在一半的时间内完成并显示结果。所以它显然更快。但是,我现在有时会在某些部分实体类方法中获取有关null引用异常等的错误消息。即使我测试相同的数据,这些错误似乎也是间歇性的。我真的不明白为什么?代码不会更改或更新数据库等,而在运行代码时,没有其他任何内容正在更新数据库。在这种情况下,是否无法使用Parallel For?

更新我的错误消息是:

{"Object reference not set to an instance of an object."}

堆栈追踪:

   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)

错误行对应于此处的代码:

  public fixture GetNextFixture(fixture fixture)
    {
          fixtureperiod fixtureperiod = fixture.GetMostRecentFixturePeriod();

所以fixture是null但是如果我运行非并行版本

,似乎永远不会发生同样的事情

由于

格雷姆

1 个答案:

答案 0 :(得分:4)

您的模型似乎是一个懒惰评估的结构,依赖于实体框架上下文。实体框架上下文不是线程安全的。尝试在非并行操作中从上下文中提取所有数据,然后将映射作为并行操作进行处理。

Parallel.ForEach(Model.ToList(), ...