簡體   English   中英

讓! 按順序執行?

[英]Let! executing in sequence?

我的印象就是讓! 在f#中,智能足以在並行中執行賦值序列。 但是,以下示例顯示不同的行為,a,b,c的分配似乎同步執行。

    let sleep sec =
        async
            {
                System.Threading.Thread.Sleep(sec * 1000)
                return sec
            }

    let bar = async 
                {
                    let! a = sleep 1
                    let! b = sleep 3
                    let! c = sleep 3
                    return a+b+c
                }

    let foo = Async.RunSynchronously(bar)
    printfn "%d" foo

那是怎么回事?

如果我想在並行執行a,b,c,我應該使用Async.Parallell ... |> Async.RunSynchronously ...然后呢?

上面的示例是無用的,真正的用例就像查詢數據庫並同時調用一些web服務。

正如Richard指出的那樣,異步工作流仍然是完全順序的。 我認為任何試圖進行全自動並行化的項目都沒有完全成功,因為這樣做太難了。

但是,異步工作流仍然可以使並行化更容易。 關鍵是它們可以在不阻塞線程的情況下進行等待(這對於可伸縮性至關重要),並且它們還支持自動取消和簡單的異常處理,使您的生活更輕松。 有各種模式允許您在異步工作流中並行化代碼。

  • 基於任務的你可以在后台啟動你的三個任務,然后等到所有這些任務完成(這可能就是你所期望的,所以這里是如何明確寫出來的):

     let bar = async { let! atask = sleep 1 |> Async.StartChild let! btask = sleep 3 |> Async.StartChild let! ctask = sleep 3 |> Async.StartChild let! a = atask let! b = btask let! c = ctask return a + b + c } 
  • 數據並行 - 如果您有多個相同類型的工作流,則可以使用Async.Parallel創建一個並行運行所有這些工作流的工作流。 當你然后使用let! 它運行所有三個任務並等待它們完成:

     let bar = async { let! all = Async.Parallel [ sleep 1; sleep 3; sleep 3 ] return all.[0] + all.[1] + all.[2] } 

Don Syme有一篇文章討論基於異步工作流的各種模式 ,您可以在財務儀表板示例中找到一個全面的示例

let! ,在async塊(或更正確的“計算表達式”)中異步執行表達式,但整個塊仍然是線性執行的。 這是async計算表達式的好處:通過為您執行連續傳遞,使一系列依賴異步操作更容易編寫。

(其他類型的計算表達式為let!yield!等提供了自己的語義)

要執行並行/並發執行,您需要單獨執行多個async表達式。

我受到了印象

你誤解了(很容易理解)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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