在过去的几天里,我一直在为F#中的并行和异步构造而苦苦挣扎,并且不知道在这一点上要去哪里。我用F#编程了大约4个月 - 当然没有专家 - 我目前有一系列计算在F#(asp.net 4.5)中实现,并且在顺序执行时正常工作。我在多核服务器上运行计算,因为有数百万个输入来执行相同的计算,我希望利用并行性来加速它。
计算非常数据并行 - 基本上是对不同输入数据的精确计算。我已经尝试了许多不同的途径,并且我不断遇到同样的问题 - 似乎并行循环永远不会到达输入数据集的末尾。我已经尝试过TPL,ConcurrentQueues,Parallel.Array.map / it和所有相同的结果:程序开始很好,然后在中间的某个地方(不确定)它只是挂起而永远不会完成。为简单起见,我实际上从程序中删除了计算,我只是调用一个print方法,这里是代码当前的位置:
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
几点...... 我将上面的结果限制为仅用于调试。实际程序不适用Take(5)。 testParallel方法只是一个printfn“test”。
customerInputArray是一种复杂的数据类型。它是包含记录的列表元组。所以我很确定我的问题必须在那里......但我添加了异常处理,没有异常被提出,所以不知道如何找到问题。
感谢任何帮助。提前谢谢。
编辑:感谢您的建议......我认为这绝对是僵局。当我删除所有printfn,sprintfn和字符串concat操作时,它就完成了。 (当然,我需要那些东西。)printfn,sprintfn和string ops不是线程安全的吗?
另一个编辑:迭代总是在最后一个项目上停止。因此,如果我的输入数组有15个项目,则处理在项目14上停止,或者似乎永远不会到达项目15.然后一切都会挂起。无论输入数组的大小是什么。任何想法可能导致什么?我甚至切换到Parallel.ForEach(而不是Array.Parallel)和相同的行为。
答案 0 :(得分:1)
有关情况的更新以及我如何解决此问题。
由于我公司的防火墙政策,我无法从我的示例上传代码,所以最后我的问题没有足够的细节。我没有提到我使用的类型提供程序在这种情况下是重要的信息。但这是我想出来的。
我正在使用SQL Server的F#类型提供程序,并且传递了我怀疑不是线程安全的服务类型。当我用普通的旧F#Records替换ServiceTypes时,代码工作正常 - 没有更多的死锁,一切都完成而没有错误。