我遇到了实现并行的问题因为它似乎间歇性地导致错误消息。
我正在尝试加快映射使用大量导航属性等构建的复杂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但是如果我运行非并行版本
,似乎永远不会发生同样的事情由于
格雷姆
答案 0 :(得分:4)
您的模型似乎是一个懒惰评估的结构,依赖于实体框架上下文。实体框架上下文不是线程安全的。尝试在非并行操作中从上下文中提取所有数据,然后将映射作为并行操作进行处理。
Parallel.ForEach(Model.ToList(), ...