我正在尝试使用MailboxProcessor建模异步作业处理框架。我的要求是启动,停止,暂停和恢复作业处理器。我可以使用MailboxProcessor构建暂停/恢复功能吗?我也应该能够停下来开始吗?我试图在Windows服务后建模。
我在C#中使用Queue / Threads实现了一个系统。我正在寻找设计替代品,就在我看到MailboxProcessor的时候。我相信我可以使用它,但无法弄清楚如何处理上述情况。那么有可能实现这个功能吗?
答案 0 :(得分:9)
当然:)只需保留一个内部作业队列,并在作业处理器处于启动模式时通过队列进行枚举。在任何其他模式下,只需将新作业排入队列,直到处理器进入启动模式。
type 'a msg = // '
| Start
| Stop
| Pause
| Job of (unit -> unit)
type processQueue() =
let mb = MailboxProcessor.Start(fun inbox ->
let rec loop state (jobs : System.Collections.Generic.Queue<_>) =
async {
if state = Start then
while jobs.Count > 0 do
let f = jobs.Dequeue()
f()
let! msg = inbox.Receive()
match msg with
| Start -> return! loop Start jobs
| Pause -> return! loop Pause jobs
| Job(f) -> jobs.Enqueue(f); return! loop state jobs
| Stop -> return ()
}
loop Start (new System.Collections.Generic.Queue<_>()))
member this.Resume() = mb.Post(Start)
member this.Stop() = mb.Post(Stop)
member this.Pause() = mb.Post(Pause)
member this.QueueJob(f) = mb.Post(Job f)
此类的行为符合预期:您可以将作业排入暂停状态,但它们只能在“开始”状态下运行。一旦processQueue停止,它就无法重新启动,并且所有排队的作业都不会运行(它很容易改变这种行为,因此,它不会杀死队列,而只是不会将作业排入Stop状态)。
如果您需要邮箱处理器和代码之间的双向通信,请使用MailboxProcessor.PostAndReply。
答案 1 :(得分:3)
您可能需要查看Luca's blog,因为我认为它有some recent relevant stuff。