包装
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
}
我认为你可以只使用 for 循环:
async {
for item in 1..10 do
do! Async.Sleep 1000
printfn $"item: {item}"
}