2011-08-01 13 views
5

の違いこのような何かを書くことの違いはあります:F#の非同期 - 2つの構造

MailboxProcessor.Start(fun inbox -> async { 
    let rec loop bugs = 
     let! msg = inbox.Receive() 
     let res = //something 
     loop res 
    loop []}) 

そして、このようにそれを書く:

MailboxProcessor.Start(fun inbox -> 
    let rec loop bugs = async { 
     let! msg = inbox.Receive() 
     let res = //something 
     do! loop res } 
    loop []) 

ありがとう!

答えて

7

最初の例は有効なF#コードではありません。let!は計算式の中でのみ使用できます。あなたの例では、普通の関数で使っています。その本体は計算式ではないので、let!はその位置では使用できません。 - その後、あなただけ使用する必要が

MailboxProcessor.Start(fun inbox -> async { 
    let rec loop bugs = async { 
     let! msg = inbox.Receive() 
     let res = //something 
     return! loop res } 
    return! loop []}) 

あなたにもスニペットで外async { .. }ブロックを保つことができます。

あなたは asyncloop関数の本体をラップする必要があるだろう、それが有効にするには return!を返すだけでなく、 loop関数を呼び出すことができます(ただし、今のところ大きな違いはありません)。

do!の代わりにreturn!を使用しました。return!は残りの現在の本文を破棄できるので、実際には違いがあります。 do!を使用すると、asyncはヒープ内のスタックフレームのようなものを割り当てます。したがって、再帰的ループ関数のdo!を使用するとメモリがリークします。

+2

最初に動作するかどうかわからなかったのはなぜですか? – ChaosPandion

+1

ここに私は家に帰ったときに、私のアプリがすべて私のシステムでクラッシュして仮想メモリから出てきた理由が不思議でした! ありがとうトマス! –

+0

@ChaosPandion非常に良い点は、私は別の理由でコンパイルしていないコードを試していて、私が見ていたものを想定していました。質問を投票するのは自由ですが、Tomasの答えはとにかく便利でした。 –

関連する問題