16.4.4 封装邮箱处理器

728 篇文章 1 订阅
38 篇文章 0 订阅
 

16.4.4 封装邮箱处理器

 

    为了封装处理器邮箱,需要把表示处理器的全局值,改成在通常的对象类型内的本地字段。还要添加发送消息到私有邮箱的方法,这也有益于封装:我们不必要公开邮箱可以响应的所有消息,如果有一些仅供内部使用的话。

    此更改不需要对消息处理代码做任何修改。在清单 16.17 中,可以看到具体对象类型的声明,处理代码本身则省略了,因为它没有改变。

 

Listing 16.17 Encapsulating mailbox processor into a type (F#)

 

type DrawingState() =
  let mbox = MailboxProcessor.Start(fun mbox –>
    let rec loop(clr, rects) = async {
      let! msg = mbox.Receive()
      // Message processing code as before
    }
    loop(Color.Black, []) )

  member x.SetColor(clr) =
    mbox.Post(SetColor(clr))
  member x.AddRectangle(rc) =
    mbox.Post(AddRectangle(rc))

  member x.AsyncGetRectangles() =
    mbox.PostAndAsyncReply(GetRectangles))
  member x.AsyncGetColor() =
    mbox.PostAndAsyncReply(GetColor))

  member x.GetRectangles() =
    mbox.PostAndReply(GetRectangles)
  member x.GetColor() =
    mbox.PostAndReply(GetColor)

let state = new DrawingState()

 

    为了在类声明中创建本地邮箱处理器,我们使用了一个本地 let 绑定,这成为类构造函数的一部分,这意味着,邮箱将在创建实例时启动。使用本地 let 绑定声明的值,都变成了字段,这样,就可以从类中的任何地方访问它们。

    类型的成员通常是样板代码。这些成员使用 Post 方法发送消息,更新邮箱处理器的状态,并不等待任何返回的值。第二组成员异步读取状态,使用 PostAndAsyncReply 方法。注意,我们在命名这些成员时,使用了 Async 前缀,在整个 F# 库中,表示只能从异步工作流访问的成员,这是标准的表示法。最后的两个方法简单地阻塞了方法,它们使用了同步的 PostAndReply 方法。

    把邮箱处理器封装到类中,还需要修改访问它的其余代码。不需要明确发送一条消息,只需调用其中的一个方法。例如,在异步工作流中,获取和设置所选颜色的调用,就变成了这样:

 

let! clr = state.AsyncGetColor()
state.SetColor(clr)

 

    现在,我们已经在类中封装了邮箱处理器,就能把它编译成 F# 库,作为一个可重用的组件发布。不幸的是,很难从 C#  中,使用这些返回异步工作流对象(Async<'T>)的方法,所以,如果希望能够从 C# 中使用这个组件,还应提供一些方法,这需要一个委托作为回调,并异步操作完成时运行它。

    下一节中,我们会添加更多的功能到我们的应用程序中,展示事件处理的另一个方面,在异步工作流中使用 AwaitObservable 基元。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值