2

クラスにラップされた F# 3.0 エージェントがあります。

type AgentWrapper() =
    let myAgent = Agent.Start(fun inbox ->
            let rec loop (state: int) =
                async {
                    let! (replyChannel: AsyncReplyChannel<int>) = inbox.Receive()
                    let newState = state + 1
                    replyChannel.Reply newState
                    return! loop newState
                }
            loop 0 )

    member private this.agent = myAgent

    member this.Send () = 
        this.agent.PostAndReply (fun replyChannel -> replyChannel)

次のようにメッセージを送信すると:

let f = new AgentWrapper ()
f.Send () |> printf "Reply: %d\n"
f.Send () |> printf "Reply: %d\n"
f.Send () |> printf "Reply: %d\n"

期待される応答が得られます。

Reply: 1
Reply: 2
Reply: 3

ただし、エージェントの let バインディングを削除し、直接 this.agent プロパティに割り当てると:

type AgentWrapper() =

    member private this.agent = Agent.Start(fun inbox ->
            let rec loop (state: int) =
                async {
                    let! (replyChannel: AsyncReplyChannel<int>) = inbox.Receive()
                    let newState = state + 1
                    replyChannel.Reply newState
                    return! loop newState
                }
            loop 0 )

    member this.Send () = 
        this.agent.PostAndReply (fun replyChannel -> replyChannel)

次に、応答を取得します。

Reply: 1
Reply: 1
Reply: 1

私はこれを何時間も見つめてきましたが、AgentWrapper.Send を呼び出すたびにエージェントが再初期化される理由がわかりません。this.agent を呼び出すたびに再割り当てされているように感じます (つまり、プロパティではなくメソッドのように動作します)。私は何が欠けていますか?

4

1 に答える 1

3

this.agent を呼び出すたびに再割り当てされているように感じます (つまり、プロパティではなくメソッドのように動作します)。私は何が欠けていますか?

これはまさに起こることであり、仕様に文書化されています (18.13.1 からの関連部分が続きます)

静的およびインスタンス プロパティ メンバーは、メンバーが呼び出されるたびに評価されます。たとえば、次の例では、C.Time が評価されるたびにメンバーの本体が評価されます。

タイプ C () =

static member Time = System.DateTime.Now

これはあなたの状況に似ています

于 2013-02-26T10:22:14.923 に答える