[英]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.