【发布时间】:2014-02-07 12:02:35
【问题描述】:
我一定是在某处做错了,因为我的并发包中有重复的项目,这是事件链
var listings = new ConcurrentBag<JSonListing>();
Parallel.ForEach(Types, ParallelOptions, (type, state) =>
{
...
status = ProcessType(listings, status, type, state);
....
});
private GeocodeResults ProcessType(ConcurrentBag<JSonListing> listings, GeocodeResults status, XElement type, ParallelLoopState state)
{
....
AddListingsToList(results, type, listings);
....
}
private void AddListingsToList(dynamic results, XElement type, ConcurrentBag<JSonListing> listings)
{
var typeMustMatch = type.Attribute("TypeMustMatch").Value;
var typeID = Convert.ToInt32(type.Attribute("ID").Value);
foreach (var result in results.results)
{
var foundListing = listings.SingleOrDefault(x => x.ID == result.id);
if (foundListing != null)
{
var typeIDs = foundListing.TypeIDs.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
if (!typeIDs.Contains(typeID.ToString()))
{
foundListing.TypeIDs += "|" + typeID;
}
}
else
{
var listing = new JSonListing { ID = result.id, ReferenceNumber = result.reference, TypeIDs = typeID.ToString(), TypeMustMatch = typeMustMatch };
listings.Add(listing);
}
}
}
添加列表应保证如果元素已经存在,则不会添加另一个相同 ID 的元素,而是更新某些属性。 现在我得到的错误是
System.InvalidOperationException:序列包含多个匹配元素
在 System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 源,Func`2 谓词)
在 LocalSearch.Processor.CityProcessor.AddListingsToList(对象结果,XElement 类型,ConcurrentBag`1 列表)在 d:\Projects\ListingLocator2\Code\LocalSearch.Processor\Processors.cs:line 310
在 CallSite.Target(Closure , CallSite , CityProcessor , Object , XElement , ConcurrentBag`1 )
在 LocalSearch.Processor.CityProcessor.ProcessType(ConcurrentBag`1 列表,GeocodeResults 状态,XElement 类型,ParallelLoopState 状态)在 d:\Projects\ListingLocator2\Code\LocalSearch.Processor\Processors.cs:line 249
在 LocalSearch.Processor.CityProcessor.c__DisplayClass4.b__0(XElement type, ParallelLoopState state) in d:\Projects\ListingLocator2\Code\LocalSearch.Processor\Processors.cs:line 137
【问题讨论】:
-
使用 PLINQ 可以更干净地解决这个问题。
-
@spender:看起来
ProcessType会有显着的副作用,但示例中已省略。 -
@spender ProcessType 的唯一方法是调用(或多次调用)google places api,它返回与搜索查询匹配的可用位置的动态列表。 PLINQ 不适用于此,因为这些不在内存项中。