簡體   English   中英

無法通過郵箱處理器(F#)保持狀態

[英]Unable to keep state with mailbox processor (F#)

我正在嘗試創建一個字符串列表,該列表將在郵箱處理器的幫助下逐步將元素逐步異步插入。 但是我沒有得到想要的輸出。

我幾乎遵循了https://fsharpforfunandprofit.com/posts/concurrency-actor-model/中的代碼,但是對於我來說,它似乎無法正常工作。 我的代碼如下:

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 

我一直得到的結果只是最新輸入的列表,不保留狀態。 因此,如果我輸入“ a”,然后輸入“ b”,然后輸入“ c”,則隊列將僅具有值“ c”,而不是“ a”;“ b”;“ c”

任何幫助或指針將不勝感激!

就像C#屬性一樣 ,您的Agent實際上是一個屬性,因此其行為類似於帶有void參數的方法。 這就是為什么每次訪問“ Agent屬性時都會獲得一個新代理的原因。

在慣用的F#中,實現代理時有兩種樣式。 如果不需要很多代理實例,只需編寫一個模塊,然后將與代理相關的內容封裝在其中。 否則,應使用OOP樣式。

樣式#1的代碼

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 ()

樣式#2的代碼

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 ()

請注意,對於Queue類型,使用了單案例聯合類型

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM