2012-04-23 44 views
0

試圖使用Blocking Queue實現讀寫器問題,代碼爲here。 編譯並運行整個事件,但reader()和writer()函數中async {...}中的部分不產生任何輸出。我很確定他們被正確調用,因爲即使我是F#的noob,這個代碼的教程頁似乎是真實的。使用F#在異步函數中沒有輸出?

這裏是整個代碼:

open System 
open System.IO 
open System.Collections.Generic 
//open System.Runtime.Serialization.Formatters.Binary 

///defining Agent 
type Agent<'T> = MailboxProcessor<'T> 

///defining Message 
type internal BlockingAgentMessage<'T> = 
    | Get of AsyncReplyChannel<'T> 
    | Add of 'T * AsyncReplyChannel<unit> 

/// Agent-based implementation of producer/consumer problem 
type BlockingQueueAgent<'T>(maxLength) = 
    let agent = Agent.Start(fun agent -> 
     let queue = new Queue<_>() 
     //let queue = new Queue() 
     // State machine running inside the agent 
     let rec emptyQueue() = 
      agent.Scan(fun msg -> 
       match msg with 
       | Add(value, reply) -> Some(enqueueAndContinue(value, reply)) 
       | _ -> None) 
     and fullQueue() = 
      agent.Scan(fun msg -> 
       match msg with 
       | Get(reply) -> Some(dequeueAndContinue(reply)) 
       | _ -> None) 
     and runningQueue() = async { 
      let! msg = agent.Receive() 
      match msg with 
      | Add(value, reply) -> return! enqueueAndContinue(value, reply) 
      | Get(reply) -> return! dequeueAndContinue(reply) } 
     and enqueueAndContinue (value, reply) = async { 
      queue.Enqueue(value) 
      reply.Reply() 
      return! chooseState() } 
     and dequeueAndContinue (reply) = async { 
      reply.Reply(queue.Dequeue()) 
      return! chooseState() } 
     and chooseState() = 
      if queue.Count = 0 then emptyQueue() 
      elif queue.Count = maxLength then fullQueue() 
      else runningQueue() 

     // Start with an empty queue 
     emptyQueue()) 

    /// Asynchronously adds item to the queue. If the queue 
    /// is full, it blocks until some items are removed. 
    member x.AsyncAdd(v:'T) = 
     agent.PostAndAsyncReply(fun ch -> Add(v, ch)) 

    /// Asynchronously gets item from the queue. If the queue 
    /// is empty, it blocks until some items are added. 
    member x.AsyncGet() = 
     agent.PostAndAsyncReply(Get) 




let ag = new BlockingQueueAgent<int>(3) 
printfn "Blocking Queue Agent program" 

let writer() = async { 

    for i in 0 .. 10 do 
     do! ag.AsyncAdd(i) 
     printfn "Added: %d" i } 

let reader() = async { 
    while true do 
     let! v = ag.AsyncGet() 
     do! Async.Sleep(1000) 
     printfn "Got: %d" v } 

reader() |> Async.Start 
printfn "Started Reader ..." 
writer() |> Async.Start 
printfn "Started Writer ..." 

回答

5

的代碼是好的 - 你的程序在退出之前async可以執行。只需添加如

System.Console.Read() |> ignore 

到最後。這適用於我

+0

啊喜歡在C的好日子getch()!作爲f#的noob肯定有其缺點。謝謝。 – AruniRC 2012-04-23 05:55:09