2009-06-24 54 views
3

我想模拟一个异步作业处理框架使用MailboxProcessor。我的要求是启动,停止,暂停和恢复作业处理器。我可以使用MailboxProcessor构建暂停/恢复功能吗?我也应该能够停止并开始?我试图在Windows Service之后进行建模。如何使用MailboxProcessor创建作业队列?

我在C#中使用Queue/Threads实现了一个系统。我正在寻找设计替代品,那是当我看到MailboxProcessor时。我相信我可以使用它,但无法弄清楚如何处理上述情况。那么是否有可能实现这一功能?

回答

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被停止,它就不能被重新启动,并且没有一个入队的作业会运行(它很容易改变这种行为,这样就不会杀死队列,而是不会使作业进入停止状态)。

使用MailboxProcessor.PostAndReply,如果你需要的邮箱处理器和代码之间的双向通信。

+0

+1稍微改进:可以通过使状态变为明确来使代码更加清晰。然后你也可以把所有的状态封装在`state`类型中,特别是只有`Paused`状态会有一个队列。另外,您可能希望将这些状态表示为相互递归的异步工作流程...... – 2011-04-23 23:11:06