F#奇怪的代理重新初始化行为

时间:2013-02-26 10:14:20

标签: f# mailboxprocessor

我有一个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每次调用它时都会被重新分配(即表现为方法,而不是财产)。我错过了什么?

1 个答案:

答案 0 :(得分:3)

  

感觉就像this.agent每次调用它时都会被重新分配   (即表现得像一种方法,而不是财产)。我错过了什么?

这正是发生的事情,并在规范中记录(相关部分来自18.13.1)

  

每次都会评估静态和实例属性成员   成员被调用。例如,在下面,身体的   每次评估C.Time时评估成员:

     

输入C()=

static member Time = System.DateTime.Now

这对你的情况很有帮助