对流进行限制,使写入将排队,直到收到前一次写入的响应

时间:2015-10-20 12:12:42

标签: f#

假设我有一个流,一次只允许一个请求/响应,但在多个线程中使用。

应该限制请求/命令,以便新请求只能发生一次 已发送上一个请求并已收到回复。

用户可以这样做

let! res = getResponse("longResp")
let! res2 = getResponse("shortResp")

并不是真的知道或关心油门。

我尝试使用Tomas Petricek Throttling Agent的修改版本,允许与返回值异步,但这需要用户调用getResponse("..") |> Enqueue |> w.Post这是灾难的处方(以防万一)他们忘了这样做。)

在F#中有这样做的好/惯用方法吗?

1 个答案:

答案 0 :(得分:3)

然后在你的类型系统中明确表示返回的类型需要用另一个函数解包。因此,而不是返回Async<> T>你指出的可以直接使用Async.Start调用,而是返回类似:

type Queuable<'T> = Queuable of Async<'T>

然后getResponse更改以返回Queueable:

let getResponse (s:string) =
  let r =
    async{
    do! write to your stream
    return! read from your stream
  }
Queuable r

提供解开Queuable的功能:

let enqueue (Queuable q) = async{
  return! processor.PostAndAsyncReply(fun replyChannel -> replyChannel,q)
}

处理器是一个只运行Async工作流的代理。像这样:

let processor = new MailboxProcessor<_>(fun inbox ->
  let rec Loop() = async {
    let! (r:AsyncReplyChannel<_>,job) = inbox.Receive()
    let! res = job
    r.Reply res
    return! Loop()}
  Loop())