首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >F# MailboxProcessor异步打印语句

F# MailboxProcessor异步打印语句
EN

Stack Overflow用户
提问于 2021-03-19 21:22:43
回答 2查看 125关注 0票数 0

我正在试着制作一个条形仿真器来处理订单。发送给代理的消息属于这种类型。

代码语言:javascript
复制
type DTGCafeMessage =
    | OrderDrink of Drink * float
    | LeaveAComment of string

代理是在下面实现的bar类。

代码语言:javascript
复制
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

当我向代理发送消息时,它是以一种非常混乱的方式打印东西。

代码语言:javascript
复制
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!!
(); (); (); ()]

正如我所看到的,它应该打印代码中所写的每一条语句。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-03-19 23:11:21

Fsi正在评估您的表达式。由于bar.Order()返回单元,表达式的结果是();()。所以Fsi想打印一些类似的东西

代码语言:javascript
复制
val it : unit list = [(); (); (); (); ()]

同时,邮箱处理器在另一个线程上通过它的队列工作,同时打印消息。这两个线程都在将文本发送到相同的输出,即它们是相互踩着的。

票数 4
EN

Stack Overflow用户

发布于 2021-03-21 01:37:45

就这么做

代码语言:javascript
复制
orderDrinks |> List.iter bar.Order

如果你只想打印结果。

相反,List.map将转换输出,但是输出是单位类型的,例如(),并获得所看到的乱码结果。

编辑:您还需要启动fsi静音,这样它就不会打印变量计算,例如fsi --静音

否则,这种行为是正确的,因为它显示了邮箱处理器如何开始执行任务,并在完成任务之前将控制权交给调用方。因此,调用方fsi开始打印val it: unit ()。同时邮箱处理器也在工作。两个进程同时写入控制台,产生错误的输出。

尽管如此,当您执行没有输出的函数时,仍然会使用List.Iter;这反过来只返回一个unit ()输出,而不是每个列表项返回一个unit ()。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66715755

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档