here。
使用。 NET 举例而言,我错了以下错误:
let queue = new Queue<_>()
“非基因型系统。 收集。 怀疑不会有任何类型的论据。”
如果从Quue的造物中删除了这类论点,那么,对于<条形形形形形形形形色色剂加固;T>maxLength),则通用性有所改变。
Other than implementing my own queue class, is there any way to use the .NET Queue class as used in the sample program? The entire code is given below, in case that s more illustrative.
open System
open System.IO
open System.Collections
//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)
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
writer () |> Async.Start