簡體   English   中英

為什么需要使用“做! F#異步工作流中的異步“樣式函數?

[英]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 2000do 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM