[英]Can you use Thread.CurrentPrincipal with F# async workflows?
[英]Why the need for usage of “do! Async” style functions within F# Async Workflows?
我是F#Async工作流程的新手。 通常,介紹此主題的代碼和示例包含以下示例(簡化):
let sleepWorkflow =
async{
printfn "Starting sleep workflow at %O" DateTime.Now.TimeOfDay
do! Async.Sleep 2000
printfn "Finished sleep workflow at %O" DateTime.Now.TimeOfDay
}
Async.RunSynchronously sleepWorkflow
我想了解do! Async.Sleep 2000
的必要性do! Async.Sleep 2000
do! Async.Sleep 2000
與do Threading.Thread.Sleep(2000)
相反。
根據我的理解,BOTH方法將在此時同步運行代碼。
有什么區別(我認為必須有),什么時候應該使用一種方法而不是另一種?
區別在於使用Thread.Sleep
阻止當前線程,以便在Async.Sleep
創建系統計時器時不會執行任何其他Async.Sleep
,釋放當前線程(以便它可以執行其他操作)然后(在時間過去之后)獲取再次運行一個線程並運行其余的代碼。
如果您有大量並行運行的async
工作流(因為每個工作站的專用線程都很昂貴)或者在GUI線程上運行代碼(只有一個線程且不應阻止它),這一點很重要。
為了更好地理解這一點,您可以將線程池線程數更改為1,並使用同步和異步阻塞嘗試以下代碼:
System.Threading.ThreadPool.SetMinThreads(1, 1)
System.Threading.ThreadPool.SetMaxThreads(1, 1)
for i in 1 .. 5 do
async { System.Threading.Thread.Sleep(1000)
printfn "Done" } |> Async.Start
for i in 1 .. 5 do
async { do! Async.Sleep(1000)
printfn "Done" } |> Async.Start
運行第一個for
循環后,您將打印“完成”消息,延遲時間為1秒(因為一個線程被重復阻止1秒)。
運行第二個for
循環后,您將看到1秒鍾后立即打印“完成”消息。 這是因為異步等待實際上並沒有阻塞線程,因此5個定時器將全部經過,然后使用1個可用線程進行打印(這幾乎不需要時間)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.