Hopac timeOutMillis无法按预期工作

时间:2016-11-01 05:24:32

标签: f# hopac

我最近开始和Hopac一起玩,并认为这真是太棒了。然而,这是一个我无法解决的问题。以下是代码段:

let rnd = new Random()

let logger (msg:string) =
    let c = Ch<string>()
    let msgLoop = job {
        for i in [1..15] do 
            let msgStr = sprintf "%s %d" msg i
            do! timeOutMillis (rnd.Next(1000,3000))
            do! c *<- msgStr
    }
    printfn "Started job %s" msg 
    msgLoop |> start
    c

let timeout = timeOutMillis 3000

let c = logger "Instance Foo"
let rec printLoop () = Job.delay <| fun () -> 
    Alt.choose[
            timeout ^=> fun () -> printfn "job timed out"
                                  Job.result ()
            Ch.take c ^=> fun msg -> printfn "Log: %s" msg
                                     printLoop ()
    ]
printLoop () |> start

我认为在经过3000毫秒后,超时备选将变为可用并将中止打印消息。这种情况不会发生,只有当通道c中没有任何内容时,才会触发超时。

我在Alt.choose列表的第一个位置放置了超时,因为根据文档,如果同时有多个备选方案,那么列表中首先出现的那个被选中 (On the Semantics of Alternatives

非常感谢任何帮助

1 个答案:

答案 0 :(得分:1)

这是一个快速回答。超时未在该行开始:

let timeout = timeOutMillis 3000

相反,超时是在行重新开始的

 timeout ^=> fun () -> printfn "job timed out"

每次评估该行。对程序的最短修复是将您定义超时的行更改为:

let timeout = timeOutMillis 3000 |> memo