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 回答