2011-03-22 129 views
0

我正在將標準ASP.NET網站的網站轉換爲使用Azure。該網站之前已經將管理用戶上傳的Excel文件保存在文件系統中。作爲遷移的一部分,我將此文件保存到Azure存儲。在通過Azure SDK運行本地存儲時,它工作正常。 (因爲我不想在開發過程中進行升級,所以我使用的是1.3版本。)將文件上傳到Azure存儲時出現錯誤

當我將代碼指向Azure存儲本身運行時,該過程通常會失敗。我得到的錯誤是: System.IO.IOException發生

Message=Unable to read data from the transport connection: The connection was closed. 
    Source=Microsoft.WindowsAzure.StorageClient 
    StackTrace: 
     at Microsoft.WindowsAzure.StorageClient.Tasks.Task`1.get_Result() 
     at Microsoft.WindowsAzure.StorageClient.Tasks.Task`1.ExecuteAndWait() 
     at Microsoft.WindowsAzure.StorageClient.CloudBlob.UploadFromStream(Stream source, BlobRequestOptions options) 
     at Framework.Common.AzureBlobInteraction.UploadToBlob(Stream stream, String BlobContainerName, String fileName, String contentType) in C:\Development\RateSolution2010\Framework.Common\AzureBlobInteraction.cs:line 95 
    InnerException: 

的代碼如下:

public void UploadToBlob(Stream stream, string BlobContainerName, string fileName, 
     string contentType) 
    { 
     // Setup the connection to Windows Azure Storage 
     CloudStorageAccount storageAccount = CloudStorageAccount.Parse(GetConnStr()); 

     DiagnosticMonitorConfiguration dmc = DiagnosticMonitor.GetDefaultInitialConfiguration(); 
     dmc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1); 
     dmc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose; 
     DiagnosticMonitor.Start(storageAccount, dmc);  
     CloudBlobClient BlobClient = null; 
     CloudBlobContainer BlobContainer = null; 
     BlobClient = storageAccount.CreateCloudBlobClient(); 

     // For large file copies you need to set up a custom timeout period 
     // and using parallel settings appears to spread the copy across multiple threads 
     // if you have big bandwidth you can increase the thread number below 
     // because Azure accepts blobs broken into blocks in any order of arrival. 
     BlobClient.Timeout = new System.TimeSpan(1, 0, 0); 
     Role serviceRole = RoleEnvironment.Roles.Where(s => s.Value.Name == "OnlineRates.Web").First().Value; 
     BlobClient.ParallelOperationThreadCount = serviceRole.Instances.Count; 

     // Get and create the container 
     BlobContainer = BlobClient.GetContainerReference(BlobContainerName); 
     BlobContainer.CreateIfNotExist(); 

     //delete prior version if one exists 
     BlobRequestOptions options = new BlobRequestOptions(); 
     options.DeleteSnapshotsOption = DeleteSnapshotsOption.None; 
     CloudBlob blobToDelete = BlobContainer.GetBlobReference(fileName); 
     Trace.WriteLine("Blob " + fileName + " deleted to be replaced by newer version."); 
     blobToDelete.DeleteIfExists(options); 

     //set stream to starting position 
     stream.Position = 0; 
     long totalBytes = 0; 
     //Open the stream and read it back. 
     using (stream) 
     { 
      // Create the Blob and upload the file 
      CloudBlockBlob blob = BlobContainer.GetBlockBlobReference(fileName); 
      try 
      { 
       BlobClient.ResponseReceived += new EventHandler<ResponseReceivedEventArgs>((obj, responseReceivedEventArgs) 
       => 
       { 
        if (responseReceivedEventArgs.RequestUri.ToString().Contains("comp=block&blockid")) 
        { 
         totalBytes += Int64.Parse(responseReceivedEventArgs.RequestHeaders["Content-Length"]); 
        } 
       });     
       blob.UploadFromStream(stream); 
       // Set the metadata into the blob 
       blob.Metadata["FileName"] = fileName; 
       blob.SetMetadata(); 
       // Set the properties 
       blob.Properties.ContentType = contentType; 
       blob.SetProperties(); 
      } 
      catch (Exception exc) 
      { 
       Logging.ExceptionLogger.LogEx(exc); 
      } 
     } 
    } 

我已經嘗試了許多不同的變化來驗證碼:刪除之前的blob替換它(雖然問題也存在於新的blob上),設置容器權限,不設置權限等。

感謝您提供任何幫助。

+0

我會對代碼進行一些更改,但它們不應導致出現問題。你真的需要totalBytes嗎?您是否嘗試過沒有收到響應事件處理程序? – knightpfhor 2011-03-22 21:02:54

+0

事件處理程序只是爲了查看是否有任何事情隨傳輸而發生。它似乎沒有在性能上有所作爲。 – 2011-03-23 12:50:45

+0

另外,我應該問:這段代碼運行在一個單獨的項目中,並作爲DLL被編譯到Web角色中。 (網絡角色只是一個Web解決方案項目。)這是否有所作爲?代碼是否需要真正在角色本身中? (我對此表示懷疑,因爲它偶爾會工作,但我認爲我應該問一下。) – 2011-03-23 12:52:53

回答

0

問題原來是筆記本電腦上的防火牆設置。這是我最初在家中設置的個人筆記本電腦,因此防火牆規則未針對企業環境設置,導致上傳和下載性能下降。

0

您的代碼看起來應該可以工作,但它有許多額外的功能並非嚴格要求。我會把它降到絕對最低限度,並從那裏開始。這真的只是一種直覺,但我認爲這可能是使用聲明給你的悲傷。這enture功能可以寫成(假定容器已經存在)爲:

public void UploadToBlob(Stream stream, string BlobContainerName, string fileName, 
       string contentType) 
      { 
       // Setup the connection to Windows Azure Storage 
       CloudStorageAccount storageAccount = CloudStorageAccount.Parse(GetConnStr()); 
       CloudBlobClient BlobClient = storageAccount.CreateCloudBlobClient(); 
       CloudBlobContainer BlobContainer = BlobClient.GetContainerReference(BlobContainerName); 
       CloudBlockBlob blob = BlobContainer.GetBlockBlobReference(fileName); 
       stream.Position = 0; 
       blob.UploadFromStream(stream); 
      } 

的東西,注意到我已經刪除:

  • 您應該建立診斷只有一次,當你的應用程序開始,不是每次調用某個方法。通常在RoleEntryPoint.OnStart()
  • 我不確定爲什麼你試圖設置ParallelOperationThreadCount如果你有更多的實例。這兩件事似乎沒有關係。
  • 每次你爲它保存一些東西時,檢查一個容器/表的存在是不好的形式。在您的應用程序啓動時進行一次檢查或者在網站外部有一個進程以確保所有必需的容器/表/隊列存在時更常見。當然,如果你試圖動態創建容器,這是不正確的。
相關問題