2012-09-28 44 views
0

我很困惑與異步上傳blob的問題,希望在這裏找到答案。混淆約EndUploadFromStream

請看看我的代碼段第一,

public void UploadMultipleBlobs(List<string> filelocations, string containerName, AsyncCallback callback = null, string path = null) 
    { 
        try 
     { 

      Parallel.ForEach(filelocations, fileLocation => 
       { 

        //File to Stream 
        MemoryStream str = new MemoryStream(); 
        byte[] file = File.ReadAllBytes(fileLocation); 
        str.Write(file, 0, file.Length); 
        str.Seek(0, SeekOrigin.Begin); 

        //Operations 
        if (callback == null) 
         callback = new AsyncCallback(OnUploadCompleted); 
        BlobRequestOptions blobRequestOptions = new BlobRequestOptions(); 
        blobRequestOptions.Timeout = new TimeSpan(1, 0, 0); 
        blobRequestOptions.RetryPolicy = retry; 

        CloudBlob currentBlob = container.GetBlobReference(blobName); 
        var result = currentBlob.BeginUploadFromStream(str, blobRequestOptions, callback, new Object[] { currentBlob, str }); 

        currentBlob.EndUploadFromStream(result); 
       }); 

     } 
     catch 
     { 
      throw; 
     } 

    } 

private void OnUploadCompleted(IAsyncResult result) 
    { 
     try 
     { 
      // Get array passed to callback 
      Object[] states = (Object[])result.AsyncState; 

      var blob = (CloudBlob)states[0]; 
      var stream = (MemoryStream)states[1]; 

      // End the operation 
      //blob.EndUploadFromStream(result); 

      // Close the stream 
      stream.Close(); 
     } 
     catch 
     { 
      throw; 
     } 
    } 

我需要牆身文件上傳到Azure的BLOB,文件的數量可能是10-50,000,每個文件約10KB-50KB。目前的代碼片段對我來說工作正常。但是,如果我在回調中調用EndUploadFromStream,則上傳超過2,000個文件時總是會引發異常。我的意思是如果我在上傳方法中刪除EndUploadFromStream並在回調(OnUploadCompleted方法)中調用EndUploadFromStream,則會發生異常。如下面異常消息:在微軟在Microsoft.WindowsAzure.StorageClient.Tasks.Task`1.get_Result()

無法讀取從傳輸連接數據:連接被關閉,堆棧跟蹤。 WindowsAzure.StorageClient.CloudBlob.EndUploadFromStream(IAsyncResult asyncResult)

我不知道它爲什麼發生......希望得到了你們的答案。

謝謝。

回答

0

開始/結束碼看起來不錯。我注意到你沒有做任何事情來等待異步操作完成,所以問題可能與此有關。例如,如果您從控制檯應用程序運行此應用程序,則應用程序可能會在所有上載完成之前退出,然後爲您提供這些錯誤。如果EndUploadFromStream()呼叫位於Parallel.ForEach()以內,這將不會成爲問題,因爲它將導致Parallel.ForEach()呼叫阻塞,直到所有上傳完成。

因此,請嘗試添加代碼以等待所有上傳完成,並查看是否修復該問題。一種簡單的方法是將一個計數器初始化爲上載總數,然後在回調內減少(使用線程安全的Interlocked.Decremement())。另一種選擇是使用Task.FromAsync()來獲取任務對象數組,然後使用Task.WaitAll()等待它們完成。另外,同時使用Parallel.ForEach()和Begin/End方法通常是多餘的 - Begin/End是異步的,所以通常沒有用多線程來調用它的要點。既然你有這麼大的物品清單可能在這種情況下有所作爲,但可能並不多。除非實際測量了顯着差異,否則最好使用簡單的foreach循環代替Parallel.ForEach()