Asynchronous 无法保持邮箱处理器(F#)的状态

Asynchronous 无法保持邮箱处理器(F#)的状态,asynchronous,f#,mailboxprocessor,Asynchronous,F#,Mailboxprocessor,我试图创建一个字符串列表,在邮箱处理器的帮助下,将元素逐渐异步插入其中。然而,我没有得到想要的输出 我基本上遵循了 然而,在我的情况下,它似乎并没有像预期的那样起作用。我的守则如下: type TransactionQueue ={ queue : string list } with static member UpdateState (msg : string) (tq : TransactionQueue) = {tq with queue = (msg :: tq.queu

我试图创建一个字符串列表,在邮箱处理器的帮助下,将元素逐渐异步插入其中。然而,我没有得到想要的输出

我基本上遵循了 然而,在我的情况下,它似乎并没有像预期的那样起作用。我的守则如下:

type TransactionQueue ={

queue : string list

} with

static member UpdateState (msg : string) (tq : TransactionQueue) =
    {tq with queue = (msg :: tq.queue)}

static member Agent = MailboxProcessor.Start(fun inbox ->
                            let rec msgLoop (t : TransactionQueue) =
                                async{
                                   let! msg = inbox.Receive()
                                   let newT = TransactionQueue.UpdateState msg t
                                   printfn "%A" newT
                                   return! msgLoop newT
                                }
                            msgLoop {queue = []}
                        )

static member Add i = TransactionQueue.Agent.Post i



[<EntryPoint>]
let main argv =

// test in isolation
printfn "welcome to test"
let rec loop () =
    let str = Console.ReadLine()
    TransactionQueue.Add str
    loop ()

loop ()



0 
类型TransactionQueue={
队列:字符串列表
}与
静态成员UpdateState(消息:字符串)(tq:TransactionQueue)=
{tq with queue=(msg::tq.queue)}
静态成员代理=MailboxProcessor.Start(有趣的收件箱->
let rec msgLoop(t:TransactionQueue)=
异步的{
let!msg=inbox.Receive()
设newT=TransactionQueue.UpdateState msg t
printfn“%A”牛顿
返回!msgLoop newT
}
msgLoop{queue=[]}
)
静态成员Add i=TransactionQueue.Agent.Post i
[]
让主argv=
//隔离试验
printfn“欢迎参加测试”
让rec循环()=
让str=Console.ReadLine()
TransactionQueue.addstr
循环()
循环()
0
我一直得到的结果只是一个最新输入的列表,状态没有保留。因此,如果我输入“a”,然后输入“b”,然后输入“c”,那么队列将只具有值“c”,而不是“a”;“b”;“c”

任何帮助或指点都将不胜感激

就像,您的
代理
实际上是一个属性,因此其行为类似于带有
void
参数的方法。这就是为什么每次访问
agent
属性时都会得到一个新代理

在惯用的F#中,实现代理时有两种风格。如果您不需要有很多代理实例,只需编写一个模块并将与代理相关的内容封装在其中。否则,应使用OOP样式

样式代码#1

模块事务队列=
type private Queue=字符串列表的队列
让private为空=队列[]
让私有更新项目(队列项目)=队列(项目::项目)
让私有代理=MailboxProcessor.Start
让rec msgLoop队列=异步{
let!msg=inbox.Receive()
return!queue |>update msg |>msgLoop
}
msgLoop空
让add item=agent.Post item
[]
让主argv=
//隔离试验
printfn“欢迎参加测试”
让rec循环()=
让str=Console.ReadLine()
TransactionQueue.add str
循环()
循环()
样式代码#2

type Queue=带有
静态成员为空=队列[]
静态成员更新项(队列项)=
队列(项::项)
类型代理()=
让agent=MailboxProcessor.Start
让rec msgLoop队列=异步{
let!msg=inbox.Receive()
return!queue |>queue.Update msg |>msgLoop
}
msgLoop队列。为空
成员this.Add item=agent.Post item
[]
让主argv=
//隔离试验
printfn“欢迎参加测试”
让代理=新代理()
让rec循环()=
让str=Console.ReadLine()
代理,添加str
循环()
循环()

请注意,
队列
类型的使用。

静态成员,如
代理
会在每次访问时进行评估,即每次调用
添加
,您都会得到一个新的
邮箱处理器
module TransactionQueue =
    type private Queue = Queue of string list
    let private empty = Queue []
    let private update item (Queue items) = Queue (item :: items)
    let private agent = MailboxProcessor.Start <| fun inbox ->
        let rec msgLoop queue = async {
            let! msg = inbox.Receive ()
            return! queue |> update msg |> msgLoop
        }
        msgLoop empty
    let add item = agent.Post item

[<EntryPoint>]
let main argv =
    // test in isolation
    printfn "welcome to test"
    let rec loop () =
        let str = Console.ReadLine()
        TransactionQueue.add str
        loop ()
    loop ()
type Queue = Queue of string list with
    static member Empty = Queue []
    static member Update item (Queue items) =
        Queue (item :: items)

type Agent () =
    let agent = MailboxProcessor.Start <| fun inbox ->
        let rec msgLoop queue = async {
            let! msg = inbox.Receive ()
            return! queue |> Queue.Update msg |> msgLoop
        }
        msgLoop Queue.Empty
    member this.Add item = agent.Post item

[<EntryPoint>]
let main argv =
    // test in isolation
    printfn "welcome to test"
    let agent = new Agent ()
    let rec loop () =
        let str = Console.ReadLine()
        agent.Add str
        loop ()
    loop ()