2009-06-24 5 views
3

私は、MailboxProcessorを使って非同期ジョブ処理フレームワークをモデル化しようとしています。私の要件は、ジョブプロセッサの開始、停止、一時停止、および再開です。 MailboxProcessorで一時停止/再開機能を構築できますか?また、私は停止し、開始することができるはずですか?私はWindowsサービスの後でモデル化しようとしています。MailboxProcessorを使用してジョブキューを作成するにはどうすればよいですか?

私はキュー/スレッドを使用して実装されたC#のシステムを持っています。私はDesign Alternativesを探していました。それは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メールボックスプロセッサとコード間の双方向通信が必要な場合は、MailboxProcessor.PostAndReplyを使用してください。

+0

+1微妙な改善:状態を明示的にすることでコードをより明確にすることができます。次に、すべての状態を 'state'型でカプセル化することができます。特に、' Paused'状態だけがキューを持ちます。また、状態を相互に再帰的な非同期ワークフローとして表現することもできます。 –

関連する問題