假设我有一个流,一次只允许一个请求/响应,但在多个线程中使用。
应该限制请求/命令,以便新请求只能发生一次 已发送上一个请求并已收到回复。
用户可以这样做
let! res = getResponse("longResp")
let! res2 = getResponse("shortResp")
并不是真的知道或关心油门。
我尝试使用Tomas Petricek Throttling Agent的修改版本,允许与返回值异步,但这需要用户调用getResponse("..") |> Enqueue |> w.Post
这是灾难的处方(以防万一)他们忘了这样做。)
在F#中有这样做的好/惯用方法吗?
答案 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())