簡體   English   中英

使用異步工作流並行化的最佳實踐

[英]Best practices to parallelize using async workflow

讓我們說我想刮一個網頁,並提取一些數據。 我最有可能寫這樣的東西:

let getAllHyperlinks(url:string) =
    async {  let req = WebRequest.Create(url)
             let! rsp = req.GetResponseAsync()
             use stream = rsp.GetResponseStream()             // depends on rsp
             use reader = new System.IO.StreamReader(stream)  // depends on stream
             let! data = reader.AsyncReadToEnd()              // depends on reader
             return extractAllUrls(data) }                    // depends on data

let! 告訴F#在另一個線程中執行代碼,然后將結果綁定到變量,並繼續處理。 上面的示例使用兩個let語句:一個用於獲取響應,一個用於讀取所有數據,因此它至少生成兩個線程(如果我錯了,請糾正我)。

雖然上面的工作流程會產生多個線程,但執行順序是串行的,因為工作流程中的每個項目都依賴於前一個項目。 在其他線程返回之前,無法在工作流程中進一步評估任何項目。

擁有多個let!有任何好處let! 在上面的代碼?

如果沒有,這個代碼將如何改變以利用多個let! 聲明?

關鍵是我們不會產生任何新線程。 在整個工作流程中,ThreadPool消耗了1或0個活動線程。 (例外,直到第一個'!',代碼在執行Async.Run的用戶線程上運行。)“let!” 當Async操作在海上時,讓我們離開一個線程,然后在操作返回時從ThreadPool中獲取一個線程。 (性能)優勢是對ThreadPool的壓力較小(當然主要的用戶優勢是簡單的編程模型 - 比您編寫的所有BeginFoo / EndFoo /回調內容要好一百萬倍)。

另見http://cs.hubfs.net/forums/thread/8262.aspx

我正在寫一個答案,但Brian打敗了我。 我完全同意他的觀點。

我想補充一點,如果你想並行化同步代碼,正確的工具是PLINQ,而不是異步工作流,就像Don Syme解釋的那樣

暫無
暫無

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

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