F#Async - 已添加具有相同键的项目

时间:2015-09-04 15:58:24

标签: asynchronous parallel-processing f#

我在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),但这不能解决。

1 个答案:

答案 0 :(得分:1)

因为两个并发查询共享相同的上下文,所以当第二个结果添加到同一个上下文时,会出现错误,指出上下文已经有一个具有相同键的项。

为每个查询使用'db'上下文的不同实例,应该可以解决您的问题。