【发布时间】:2017-03-29 16:29:27
【问题描述】:
我正在使用FSharp.Collections.ParallelSeq 和retry computation 编写刮板。我想从多个页面并行检索 HTML,并且我想在请求失败时重试请求。
例如:
open System
open FSharp.Collections.ParallelSeq
type RetryBuilder(max) =
member x.Return(a) = a // Enable 'return'
member x.Delay(f) = f // Gets wrapped body and returns it (as it is)
// so that the body is passed to 'Run'
member x.Zero() = failwith "Zero" // Support if .. then
member x.Run(f) = // Gets function created by 'Delay'
let rec loop(n) =
if n = 0 then failwith "Failed" // Number of retries exceeded
else try f() with _ -> loop(n-1)
loop max
let retry = RetryBuilder(4)
let getHtml (url : string) = retry {
Console.WriteLine("Get Url")
return 0;
}
//A property/field?
let GetHtmlForAllPages =
let pages = {1 .. 10}
let allHtml = pages |> PSeq.map(fun x -> getHtml("http://somesite.com/" + x.ToString())) |> Seq.toArray
allHtml
[<EntryPoint>]
let main argv =
let htmlForAllPages = GetHtmlForAllPages
0 // return an integer exit code
当我尝试从main 与GetHtmlForAllPages 交互时,代码似乎挂起。单步执行代码显示PSeq.map 开始处理pages 的前四个值。
发生了什么导致retry 计算表达式永远无法启动/完成? PSeq 和 retry 之间有什么奇怪的相互作用吗?
如果我将GetHtmlForAllPages 设为函数并调用它,代码将按预期工作。我很好奇GetHtmlForAllPages 是一个字段时会发生什么?
【问题讨论】: