在以下代码中,do! ag.AsyncAdd (Some i)或ag.AsyncAdd (Some i)(在函数中enqueue())均起作用。它们之间有什么区别?似乎do! ...会使入队和出队电话更加混杂?怎么样?
open FSharpx.Control
let test () =
let ag = new BlockingQueueAgent<int option>(500)
let enqueue() = async {
for i = 1 to 15 do
// ag.AsyncAdd (Some i) // works too
do! ag.AsyncAdd (Some i)
printfn "=> %d" i }
async {
do! [ for i = 1 to 10 do yield enqueue() ]
|> Async.Parallel |> Async.Ignore
for i = 1 to 5 do ag.Add None
} |> Async.Start
let rec dequeue() =
async {
let! m = ag.AsyncGet()
match m with
| Some v ->
printfn "<= %d" v
return! dequeue()
| None ->
printfn "Done"
}
[ for i = 1 to 5 do yield dequeue() ]
|> Async.Parallel |> Async.Ignore |> Async.RunSynchronously
0
Run Code Online (Sandbox Code Playgroud)
在任何F#计算表达式中,任何以结尾结尾的关键字都!倾向于表示“根据此块的规则专门处理此问题”。例如,在一个async { }块中,let!关键字的含义是“等待结果,然后将结果分配给此变量”,do!关键字的含义是“等待此异步操作,但丢弃结果,而不将其分配给任何对象”。如果您不使用do!关键字,那么您就不在等待该操作的结果。
因此,使用函数中的do!关键字enqueue,您将执行以下十五次:
AsyncAdd手术如果没有一个do!关键字,你正在做的情况如下:
AsyncAdd尽快开始15项操作听起来您似乎还不完全了解F#的计算表达式在后台如何工作。我建议阅读Scott Wlaschin的优秀网站以获取更多了解:首先https://fsharpforfunandprofit.com/posts/concurrency-async-and-parallel/然后是https://fsharpforfunandprofit.com/series/computation-expressions.html,当您阅读第二系列文章时,您将以一些现有知识为基础。