F# 中一次一个异步?

问题描述 投票:0回答:1

包装

Async<'t>
以便一次只能运行其中一个的好方法是什么?

我想出了一个使用

MailboxProcessor
的解决方案,尽管我想知道是否可以使用更轻量级的机制。

open System
open System.Threading.Tasks

let oneAtATime (workflow : Async<'t>) =
  let rec logic (taskCache : Task<'t> option) (inbox : MailboxProcessor<AsyncReplyChannel<Task<'t>>>) =
    async {
      let! channel = inbox.Receive()

      match taskCache with
      | Some task when not task.IsCompleted ->
        channel.Reply(task)

        return! logic taskCache inbox
      | _ ->
        let task = Async.StartAsTask workflow

        channel.Reply(task)

        return! logic (Some task) inbox
    }

  let actor = MailboxProcessor.Start(logic None)

  async {
    let! t = actor.PostAndAsyncReply(id)

    return! Async.AwaitTask t
  }
f#
1个回答
0
投票

我认为你可以只使用 for 循环:

async {
    for item in 1..10 do
        do! Async.Sleep 1000
        printfn $"item: {item}"
}
© www.soinside.com 2019 - 2024. All rights reserved.