Как создать очередь заданий с помощью MailboxProcessor? - PullRequest
4 голосов
/ 25 июня 2009

Я пытаюсь смоделировать среду асинхронной обработки заданий, используя MailboxProcessor. Мои требования: запустить, остановить, приостановить и возобновить работу процессора. Могу ли я создать функциональность паузы / возобновления с помощью MailboxProcessor? Также я должен быть в состоянии остановиться и начать? Я пытаюсь моделировать после службы Windows.

У меня есть система на C #, реализованная с использованием очереди / потоков. Я искал альтернативы дизайна, вот тогда я увидел MailboxProcessor. Я полагаю, что могу использовать это, но не мог понять, как обращаться с вышеупомянутыми сценариями. Так возможно ли достичь этой функциональности?

Ответы [ 2 ]

9 голосов
/ 25 июня 2009

Конечно :) Просто удерживайте внутреннюю очередь заданий и перечисляйте их, когда процессор заданий находится в режиме запуска. В любом другом режиме просто ставьте новые задания в очередь, пока процессор не перейдет в режим запуска.

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 , если вам нужна двусторонняя связь между процессором почтового ящика и вашим кодом.

3 голосов
/ 25 июня 2009

Возможно, вы захотите проверить блог Луки , так как я думаю, что он немного недавно актуально материал .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...