Async.Parallel
を試しましたか?つまり、各サブディレクトリAsync.Start
ではなく、サブディレクトリタスクをAsync.Parallel
経由で単一の非同期に結合するだけです。その後、あなたはRunSynchronously
であることができる(入れ子にされた)fork-joinタスクで終わり、最終結果を待つ。ここで
EDIT
は要点を示し、いくつかのおおよそのコード、そうでない場合は、完全な詳細です:
open System.IO
let agent = MailboxProcessor.Start(fun mbox ->
async {
while true do
let! msg = mbox.Receive()
printfn "%s" msg
})
let rec traverse dir =
async {
agent.Post(dir)
let subDirs = Directory.EnumerateDirectories(dir)
return! [for d in subDirs do yield traverse d]
|> Async.Parallel |> Async.Ignore
}
traverse "d:\\" |> Async.RunSynchronously
// now all will be traversed,
// though Post-ed messages to agent may still be in flight
EDIT 2
ここでの回答を使用して待機バージョンです:
open System.IO
let agent = MailboxProcessor.Start(fun mbox ->
async {
while true do
let! dir, (replyChannel:AsyncReplyChannel<unit>) = mbox.Receive()
printfn "%s" dir
replyChannel.Reply()
})
let rec traverse dir =
async {
let r = agent.PostAndAsyncReply(fun replyChannel -> dir, replyChannel)
let subDirs = Directory.EnumerateDirectories(dir)
do! [for d in subDirs do yield traverse d]
|> Async.Parallel |> Async.Ignore
do! r // wait for Post to finish
}
traverse "c:\\Projects\\" |> Async.RunSynchronously
// now all will be traversed to completion
解決策は何ですか?おそらくあなたは仕事を監督する1人のエージェントと、仕事を要求する多くのエージェントを使うことができます。作業者はディレクトリを探索して対応するディレクトリにファイルを取得し、結果を監督者に返信します(必ずしも最初のものと同じではない)。サブディレクトリを作業監督者に送信する – jlezard