2016-11-01 8 views
1

最近、私はHopacで遊んでいて、これは素晴らしいことだと思っています。しかし、私は頭を包むことができないという問題があります。以下のコードスニペットです:Hopac timeOutMillisが期待どおりに動作しない

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に何も残っていない場合にのみ発生します。

私は複数の選択肢が同時に使用可能な場合、リストの最初に表示されるものが (On the Semantics of Alternatives)を選んますドキュメントごとに以降最初placeinのAlt.chooseリストにタイムアウトを置い

すべてのヘルプれます高く評価しました

答えて

1

ここは簡単な回答です。 、むしろ

let timeout = timeOutMillis 3000 

タイムアウトが(再)ライン

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

にラインが評価されるたびに開始されます。タイムアウトがライン上で開始されません。プログラムの最短の修正は、タイムアウトを定義する行を次のように変更することです。

let timeout = timeOutMillis 3000 |> memo 
+0

タイムアウトが評価される度にタイムアウトが再開されることはありませんでした。今や魅力として働く –

関連する問題