[英]No output in asynchronous functions using F#?
尝试使用Blocking Queue和此处给出的代码来实现读写器问题。 整个过程都已编译并运行,但是reader()和writer()函数中async {...}中的部分均未产生任何输出。 我敢肯定他们会被正确调用,因为即使我是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 ..."
代码很好- async
执行之前,您的程序刚刚退出。 只需添加类似
System.Console.Read() |> ignore
到最后。 这对我有用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.