【问题标题】:How to terminate loop in async block?如何终止异步块中的循环?
【发布时间】:2013-10-28 21:10:10
【问题描述】:

我正在使用 Tomas 的 BlockingQueueAgent 并创建了一个 F# 控制台程序。

https://github.com/tpetricek/FSharp.AsyncExtensions/blob/master/src/Agents/BlockingQueueAgent.fs

我有以下代码。但是,该计划永远不会结束。如何在消费者中退出循环?

let producer() = 
    let addLinks = async {
        for url in links do
            do! ag.AsyncAdd(Some (url))
            printfn "Producing %s" url }
    async { do! addLinks
            do! ag.AsyncAdd(None) }

let consumer() = async {
    while true do 
        let! item = ag.AsyncGet()
        match item with 
        | Some (url) ->
            printfn "Consuming  %s" url
            ....
        | None -> 
            printfn "Done" } // How to exit the loop from here?

producer() |> Async.Start
consumer() |> Async.RunSynchronously

【问题讨论】:

  • 使用递归而不是循环。

标签: f# f#-3.0


【解决方案1】:

正如 ildjarn 建议的那样,使用递归而不是循环:

let rec consumer() = async {
    let! item = ag.AsyncGet()
    match item with
    | Some(url) ->
        printfn "Consuming %s" url
        ...
        return! consumer() // recursive call only in this case
    | None -> 
        printfn "Done" }

【讨论】:

  • 奇怪的是,有没有什么办法不使用递归函数呢?
  • @dc7a9163d9 - 当然 - 使用 ref 单元格的值作为 while 循环的保护条件,并在点击 None 时将其设置为 false。
猜你喜欢
  • 2021-12-23
  • 2022-09-24
  • 2018-01-21
  • 2018-09-18
  • 2018-10-17
  • 1970-01-01
  • 2018-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多