F# MailboxProcessor 异步混乱的打印语句
F# MailboxProcessor async messed print statements
我正在尝试制作一个处理订单的酒吧模拟器。发送给代理的消息属于这种类型。
type DTGCafeMessage =
| OrderDrink of Drink * float
| LeaveAComment of string
代理是下面实现的一个栏class。
type Bar() =
let dtgCafeAgent =
MailboxProcessor.Start
(fun inbox ->
let rec messageLoop () =
async {
let! msg = inbox.Receive()
match msg with
| OrderDrink (drink, amount) ->
let drinkPrice : float = getPrice drink
let mutable totalPrice = ((drinkPrice: float) * (amount: float))
if drink.type' = Coffee then
totalPrice <- dgtVAT totalPrice VAT
printfn
"Please pay DKK%d for your %d %A %A drinks. %s!"
(Convert.ToInt32(totalPrice))
(Convert.ToInt32(amount))
(string drink.type')
(string drink.size)
"Thanks!"
| LeaveAComment (comment) -> printf "Comment: %A" comment
return! messageLoop ()
}
messageLoop ())
member this.Order msg = dtgCafeAgent.Post msg
当我向代理发送消息时,它正在以非常混乱的方式打印内容。
let bar = Bar()
let testDrink = { type' = Coffee; size = Small }
bar.Order(OrderDrink({ type' = Coffee; size = Small }, 2.0))
let orderDrinks =
[ (OrderDrink({ type' = Coffee; size = Small }, 1.0))
(OrderDrink({ type' = Coffee; size = Medium }, 2.0))
(OrderDrink({ type' = Juice; size = Small }, 3.0))
(OrderDrink({ type' = Soda; size = Medium }, 4.0))
(OrderDrink({ type' = Milk; size = Large }, 5.0)) ]
orderDrinks |> List.map (fun o -> bar.Order o)
// output
> orderDrinks |> List.map (fun o -> bar.Order o);;
valPlease pay DKK24 for your 1 "Coffee" "Small" drinks. Thanks!!
it Please pay DKK72 for your 2 "Coffee" :"Medium" drinks. Thanks!!
unitPlease pay DKK 45 for your 3 list"Juice" "Small" drinks. Thanks!!
=Please pay DKK51 for your 4 "Soda" "Medium" drinks. Thanks!!
[()Please pay DKK;125 for your 5 "Milk" "Large" drinks. Thanks!!
(); (); (); ()]
如我所见,它应该打印代码中编写的每条语句。
Fsi 正在评估您的表情。由于 bar.Order() returns 单位,你的表达式的结果是 [(); (); (); (); ()].所以 Fsi 想要打印类似
的东西
val it : unit list = [(); (); (); (); ()]
与此同时,邮箱处理器在另一个线程上处理其队列,同时打印消息。这两个线程都将文本发送到相同的输出,即它们相互踩踏。
随心所欲
orderDrinks |> List.iter bar.Order
如果您只想打印结果。
List.map 会转换输出,但输出的类型是单位,例如() 并得到你看到的乱码结果。
编辑:您还需要安静地启动 fsi,这样它就不会打印变量评估,例如fsi --安静
否则该行为是正确的,因为它显示了邮箱处理器如何开始执行任务,并在完成之前将控制权移交给调用者。因此调用者 fsi 开始打印 val it: unit ()。
同时邮箱处理器正在工作。两个进程同时写入控制台,产生乱码输出。
当您执行没有输出的函数时仍然使用 List.Iter,例如有 unit() 输出;反过来 return 每个列表项只输出一个 unit () 而不是一个 unit ()。
我正在尝试制作一个处理订单的酒吧模拟器。发送给代理的消息属于这种类型。
type DTGCafeMessage =
| OrderDrink of Drink * float
| LeaveAComment of string
代理是下面实现的一个栏class。
type Bar() =
let dtgCafeAgent =
MailboxProcessor.Start
(fun inbox ->
let rec messageLoop () =
async {
let! msg = inbox.Receive()
match msg with
| OrderDrink (drink, amount) ->
let drinkPrice : float = getPrice drink
let mutable totalPrice = ((drinkPrice: float) * (amount: float))
if drink.type' = Coffee then
totalPrice <- dgtVAT totalPrice VAT
printfn
"Please pay DKK%d for your %d %A %A drinks. %s!"
(Convert.ToInt32(totalPrice))
(Convert.ToInt32(amount))
(string drink.type')
(string drink.size)
"Thanks!"
| LeaveAComment (comment) -> printf "Comment: %A" comment
return! messageLoop ()
}
messageLoop ())
member this.Order msg = dtgCafeAgent.Post msg
当我向代理发送消息时,它正在以非常混乱的方式打印内容。
let bar = Bar()
let testDrink = { type' = Coffee; size = Small }
bar.Order(OrderDrink({ type' = Coffee; size = Small }, 2.0))
let orderDrinks =
[ (OrderDrink({ type' = Coffee; size = Small }, 1.0))
(OrderDrink({ type' = Coffee; size = Medium }, 2.0))
(OrderDrink({ type' = Juice; size = Small }, 3.0))
(OrderDrink({ type' = Soda; size = Medium }, 4.0))
(OrderDrink({ type' = Milk; size = Large }, 5.0)) ]
orderDrinks |> List.map (fun o -> bar.Order o)
// output
> orderDrinks |> List.map (fun o -> bar.Order o);;
valPlease pay DKK24 for your 1 "Coffee" "Small" drinks. Thanks!!
it Please pay DKK72 for your 2 "Coffee" :"Medium" drinks. Thanks!!
unitPlease pay DKK 45 for your 3 list"Juice" "Small" drinks. Thanks!!
=Please pay DKK51 for your 4 "Soda" "Medium" drinks. Thanks!!
[()Please pay DKK;125 for your 5 "Milk" "Large" drinks. Thanks!!
(); (); (); ()]
如我所见,它应该打印代码中编写的每条语句。
Fsi 正在评估您的表情。由于 bar.Order() returns 单位,你的表达式的结果是 [(); (); (); (); ()].所以 Fsi 想要打印类似
的东西val it : unit list = [(); (); (); (); ()]
与此同时,邮箱处理器在另一个线程上处理其队列,同时打印消息。这两个线程都将文本发送到相同的输出,即它们相互踩踏。
随心所欲
orderDrinks |> List.iter bar.Order
如果您只想打印结果。
List.map 会转换输出,但输出的类型是单位,例如() 并得到你看到的乱码结果。
编辑:您还需要安静地启动 fsi,这样它就不会打印变量评估,例如fsi --安静
否则该行为是正确的,因为它显示了邮箱处理器如何开始执行任务,并在完成之前将控制权移交给调用者。因此调用者 fsi 开始打印 val it: unit ()。 同时邮箱处理器正在工作。两个进程同时写入控制台,产生乱码输出。
当您执行没有输出的函数时仍然使用 List.Iter,例如有 unit() 输出;反过来 return 每个列表项只输出一个 unit () 而不是一个 unit ()。