我在f#中尝试了一些异步操作,但是运气不好。我试图从数据库中获取记录并在并行的每条记录上执行操作。
let IsA1 companyId =
query { for comp in db.Company do
join cc in db.CC on (comp.CompanyId = int(cc.CompanyId))
join pp in db.PP on (cc.PartId = pp.PartId)
join tl in db.TL on (pp.CompanyId = tl.CompanyId)
where (comp.CompanyId = companyId)
select (comp.CompanyId > 0)
}
|> Seq.length |> fun len -> len > 0
let IsA2 companyId =
query { for t in db.Title do
join pp in db.PP on (t.Tid = pp.Tid)
join comp in db.Company on (pp.CompanyId = comp.CompanyId)
where (comp.CompanyId = companyId)
select (comp.CompanyId > 0)
}
|> Seq.length |> fun len -> len > 0
let GetAffiliations id =
async {
if (IsA1 id) then return "AffilBBB"
elif (IsA2 id) then return "AffilCCD"
else return Unknown
}
let ProcessCompany (company:dbSchema.ServiceTypes.Company) =
async {
let grp = GetAffiliations company.CompanyId
let result = { Id=company.CompanyId; Name=company.Name; Affiliations=grp; ContactType="ok"; }
return result
}
let GetCompanyNames =
let companies = db.Company |> Seq.distinctBy(fun d -> d.CompanyId)
companies
|> Seq.map(fun co -> ProcessCompany co)
|> Async.Parallel
|> Async.RunSynchronously
当我运行上面的代码时,我收到错误:
System.ArgumentException: An item with the same key has already been added.
由于async {}中的另一个函数调用而发生错误:
let grp = GetAffiliations company.CompanyId
我确信这是一个新手问题,但我不确定问题是什么。我甚至尝试在async {}内部调用另一个异步调用并使用let! grp = (GetAffiliations company.CompanyId)
,但这不能解决。
答案 0 :(得分:1)
因为两个并发查询共享相同的上下文,所以当第二个结果添加到同一个上下文时,会出现错误,指出上下文已经有一个具有相同键的项。
为每个查询使用'db'上下文的不同实例,应该可以解决您的问题。