我真的很喜歡F#的async
工作流程,但就我而言,它有一個嚴重問題:它不允許創建不應超過某個特定時間段的工作流。F#異步工作流程
使其更清晰,這裏有一個簡單的功能,我寫我自己:
let withTimeout operation timeout = async {
try
return Some <| Async.RunSynchronously (operation, timeout)
with :? TimeoutException -> return None
}
即簽名是
val withTimeout : operation:Async<'a> -> timeout:int -> Async<'a option>
用法示例這裏:
let op = async {
do! Async.Sleep(1000)
return 1
}
#time
withTimeout op 2000 |> Async.RunSynchronously;;
// Real: 00:00:01.116, CPU: 00:00:00.015, GC gen0: 0, gen1: 0, gen2: 0
// val it : unit option = Some 1
withTimeout op 2000 |> Async.RunSynchronously;;
// Real: 00:00:01.004, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
// val it : unit option = Some 1
withTimeout op 500 |> Async.RunSynchronously;;
// Real: 00:00:00.569, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
// val it : unit option = None
你可以看到,它按預期工作。這非常好,但它也有點尷尬,我不確定它是否會出現安全問題和其他問題。也許我正在重新發明輪子,並且有非常簡潔的方式來編寫這樣的工作流程?
這種方法的問題是,工作流將繼續超時後執行。你應該看看是否使用取消,然後在超時期限之後用信號通知取消令牌。這需要您的工作流程中的各個階段對取消通知做出響應。 – Lee
執行'Async.RunSynchronously'時,如果底層的異步操作受I/O限制,則會阻止當前線程並失去效率。我想我還沒有看到在野外的工作實現,但我記得使用一個醜陋的黑客來做到這一點,將異步comps轉換爲observables,然後合併它們。 – MisterMetaphor
@MisterMetaphor這就是爲什麼我把'RunSynchronously'換成另一個'async'的原因。我想這將允許保持併發。但這很醜,我同意。我更關心@李的話 - 我並沒有真正殺死正在運行的任務。但目前我不知道如何解決這個問題 – Rustam