1

我有以下代碼用於上傳文件夾表格本地存儲到blob存儲,包括文件夾名稱本身在blob的名稱中(代碼基於這裏找到http://blog.smarx.com/posts/pivot-odata-and-windows-azure-visual-netflix-browsing一些方法):上傳文件到Azure BLOB存儲 - Parallel.Foreach比Foreach慢

public static void UploadBlobDir(CloudBlobContainer container, string dirPath) 
     { 
      string dirName = new Uri(dirPath).Segments.Last(); 

      Parallel.ForEach(enumerateDirectoryRecursive(dirPath), file => 
       { 
        string blobName = Path.Combine(dirName, Path.GetFullPath(file)).Substring(dirPath.Length - dirName.Length); 
        container.GetBlobReference(blobName).UploadFile(file); 
       }); 
     } 

和:

private static IEnumerable<string> enumerateDirectoryRecursive(string root) 
     { 
      foreach (var file in Directory.GetFiles(root)) 
       yield return file; 
      foreach (var subdir in Directory.GetDirectories(root)) 
       foreach (var file in enumerateDirectoryRecursive(subdir)) 
        yield return file; 
     } 

此代碼的工作,並上傳如預期的文件夾,但它需要非常多的時間來完成 - 這需要20秒上傳 25個文件,每個40KB〜。所以,我累了常規一段像這樣取代並行循環:

foreach (var file in enumerateDirectoryRecursive(i_DirPath)) 
      { 
       string blobName = Path.Combine(dirName, Path.GetFullPath(file)).Substring(i_DirPath.Length - dirName.Length); 
       container.GetBlobReference(blobName).UploadFile(file); 
      } 

現在上傳完成後立即(3秒約)。

重要的是要注意,我正在針對存儲模擬器進行開發。
Parallel.Forech顯然應該更快。這種差異是否來自存儲模擬器的限制(並且在上線時,Parallel會更快),還是我可能做錯的其他事情?

回答

4

根據我的經驗,存儲模擬器告訴你嚴格地說沒有什麼關於你應該從實際的Azure存儲(或不)的性能。模擬器通常非常慢。

然後Parallel.Foreach只會在您的傳輸發生時爲延遲限制而不是I/O限制時更快。然後,請注意Parallel.Foreach將只使用您的CPU數量作爲默認並行度。對於延遲綁定的進程,通常應該有比這更多的線程,通常每個CPU有4到8個線程(YMMV)。

+0

您能否更詳細地解釋I/O綁定和延遲綁定是什麼意思,以及我的代碼屬於哪種情況? (只需提醒一下,我從本地存儲上傳,以防重要) –

+1

您可以通過使用異步傳輸獲得最大的並行性。 –

+0

@OliverBock你能更具體嗎?你的意思是使用Parallel.Foreach並在裏面調用什麼async api? –