1

在过去的几天里,我一直在努力处理 F# 中的并行和异步构造,现在不知道该去哪里。我已经用 F# 编程了大约 4 个月 - 当然不是专家 - 我目前有一系列在 F# (asp.net 4.5) 中实现的计算,并且在按顺序执行时可以正常工作。我在多核服务器上运行计算,由于有数百万个输入要执行相同的计算,我希望利用并行性来加速它。

计算是非常并行的数据 - 基本上是对不同输入数据的精确计算。我尝试了许多不同的途径,但我不断遇到同样的问题 - 似乎并行循环永远不会到达输入数据集的末尾。我已经尝试过 TPL、ConcurrentQueues、Parallel.Array.map/iter 和所有相同的结果:程序开始时很好,然后在中间的某个地方(不确定)它只是挂起并且永远不会完成。为简单起见,我实际上从程序中删除了计算,我只是调用了一个打印方法,这是代码当前所在的位置:

let runParallel = 

    let ids = query {for c in db.CustTable do select c.id} |> Seq.take(5) 

    let customerInputArray= getAllObservations ids

    Array.Parallel.iter(fun c -> testParallel c)  customerInputArray

    let key = System.Console.ReadKey()
    0

几点...我将上面的结果限制为仅 5 仅用于调试。实际程序不应用 Take(5)。testParallel 方法只是一个 printfn “测试”。

customerInputArray 是一种复杂的数据类型。它是一个包含记录的列表元组。所以我很确定我的问题一定在那里......但是我添加了异常处理并且没有引发异常,所以不知道如何去寻找问题。

任何帮助表示赞赏。提前致谢。

编辑:感谢您的建议...我认为这绝对是僵局。当我删除所有 printfn、sprintfn 和字符串 concat 操作时,它就完成了。(当然,我需要那些东西。)

printfn、sprintfn 和字符串操作不是线程安全的吗?

另一个编辑:迭代总是在最后一个项目上停止。所以如果我的输入数组有 15 个项目,则处理在项目 14 上停止,或者似乎永远不会到达项目 15。然后一切都挂起。输入数组的大小无关紧要。有什么想法会导致这种情况吗?我什至切换到 Parallel.ForEach(而不是 Array.Parallel)和相同的行为。

4

1 回答 1

1

更新情况以及我如何解决此问题。

由于我公司的防火墙政策,我无法从我的示例中上传代码,所以最后我的问题没有足够的细节。我没有提到我正在使用类型提供程序,这在这种情况下是重要的信息。但这是我想出来的。

我正在为 SQL Server 使用 F# 类型提供程序,并且正在传递我怀疑它不是线程安全的服务类型。当我用普通的旧 F# 记录替换 ServiceTypes 时,代码运行良好 - 不再出现死锁,一切都完成且没有错误。

于 2013-08-27T18:03:02.100 回答