2015-12-30 13 views
2

我有一個網站,攝影師可以上傳照片。該網站託管在一個共享的天藍色網絡應用程序和照片的照片和縮略圖上傳到Azure Blob存儲和記錄寫入數據庫。攝影師一次最多可以上傳700mb的照片。異步方法首次運行多個圖像上傳

我的問題

我曾經對A)經歷了千百年來運行和B上傳同步法)與錯誤消息「磁盤上沒有足夠的空間」失敗。我猜這是因爲Azure共享Web應用程序的臨時文件夾被限制爲200MB。

我試圖實現一種異步方法來幫助加速上傳,但它成功地完成了第一張照片(即存在斑點和數據庫記錄),然後它似乎只是掛起。這是我第一次嘗試編寫異步方法。

我也不知道如何解決臨時文件夾大小問題。

我的調用方法

public static async Task<Tuple<bool, string>> UploadAsync(HttpPostedFileBase[] photos, Bookings booking, string photoType, ApplicationUser user) 
    { 

     // For each file to be uploaded 
     foreach (HttpPostedFileBase file in photos) 
     { 
      try 
      { 
       await UploadPhotoFromFileAsync(file, user, booking.BookingsId, photoType); 

      } 
      catch (Exception ex) 
      { 
       // Not Implemented 
      } 
     } 

     return new Tuple<bool, string>(true, "Photos uploaded successfully"); 
    } 

我的照片上傳方法

public static Task UploadPhotoFromFileAsync(HttpPostedFileBase file, ApplicationUser user, int bookingId, string photoType) 
    { 
     return Task.Run(() => 
     { 
      using (ApplicationDbContext dbt = new ApplicationDbContext()) 
      { 
       Bookings booking = dbt.Bookings.Find(bookingId); 

       // Craete a new record in the UserFiles table 
       Photos photo = new Photos(); 
       photo.BookingsId = booking.BookingsId; 
       photo.PhotoType = photoType; 
       photo.FileName = Path.GetFileName(file.FileName); 

       string confirmedDate = string.Empty; 
       if (booking.ConfirmedDate.HasValue) 
       { 
        DateTime actualConfirmedDate = booking.ConfirmedDate.Value; 
        confirmedDate = actualConfirmedDate.Year.ToString() + actualConfirmedDate.Month.ToString() + actualConfirmedDate.Day.ToString(); 
       } 

       string blobName = string.Empty; 
       string blobThumbName = string.Empty; 
       if (photoType == "SamplePhoto") 
       { 
        // Get the count of the sample photos in the gallery 
        List<Photos> samplePhotos = dbt.Photos.Where(m => m.BookingsId == booking.BookingsId && m.PhotoType == "SamplePhoto").ToList(); 

        blobName = "TS_" + booking.location.Location.Replace(" ", "") + "_" + booking.BookingsId.ToString() + "_" + confirmedDate + "_" + (samplePhotos.Count).ToString() + "_sample" + Path.GetExtension(file.FileName); 
        blobThumbName = "TS_" + booking.location.Location.Replace(" ", "") + "_" + booking.BookingsId.ToString() + "_" + confirmedDate + "_" + (samplePhotos.Count).ToString() + "_sample_thumb" + Path.GetExtension(file.FileName); 
       } 
       else 
       { 
        // Get the count of the sample photos in the gallery 
        List<Photos> photos = dbt.Photos.Where(m => m.BookingsId == booking.BookingsId && m.PhotoType == "GalleryPhoto").ToList(); 

        blobName = "TS_" + booking.location.Location.Replace(" ", "") + "_" + booking.BookingsId.ToString() + "_" + confirmedDate + "_" + (photos.Count).ToString() + Path.GetExtension(file.FileName); 
        blobThumbName = "TS_" + booking.location.Location.Replace(" ", "") + "_" + booking.BookingsId.ToString() + "_" + confirmedDate + "_" + (photos.Count).ToString() + "_thumb" + Path.GetExtension(file.FileName); 
       } 

       // Create the Thumbnail image. 
       CloudBlobContainer thumbnailBlobContainer = _blobStorageService.GetCloudBlobContainer("thumbnails"); 
       if (CreateThumbnailImageFromHttpPostedFileBase(file, blobThumbName, photo)) 
       { 
        photo.ThumbnailBlobName = blobThumbName; 
        photo.ThumbnailBlobUrl = thumbnailBlobContainer.Uri + "/" + blobThumbName; 
       } 

       CloudBlobContainer blobContainer = _blobStorageService.GetCloudBlobContainer("photos"); 
       photo.BlobName = blobName; 
       photo.BlobUrl = blobContainer.Uri + "/" + blobName; 

       photo.DateCreated = DateTime.Now; 
       photo.CreatedBy = user.Id; 

       dbt.Photos.Add(photo); 
       dbt.SaveChanges(); 

       booking.Photos.Add(photo); 
       dbt.SaveChanges(); 

       //Upload to Azure Blob Storage 
       CloudBlockBlob blob = blobContainer.GetBlockBlobReference(blobName); 
       blob.UploadFromStream(file.InputStream); 
      } 
     }); 
    } 
+0

這可能有助於增加臨時文件夾大小:http://blogs.msdn.com/b/codefx/archive/2012/04/10/sample-of-apr-10th-increase-asp-net -temp-folder-size-in-windows-azure.aspx – Kayani

+0

Hi @Kayani,我看了一下,但我有一個web應用程序,而不是雲服務。你知道如何實現這個網絡應用程序? – Andrew

回答

0

的問題實際上是由在web.config中設置的請求長度引起的。它不足以允許上傳照片的大小。我只是將下面的代碼添加到Web.Config中。

<system.web> 
    <httpRuntime targetFramework="4.5" maxRequestLength="1048576" executionTimeout="900" /> 
</system.web> 
<system.webServer> 
    <modules> 
     <remove name="FormsAuthentication" /> 
    </modules> 
</system.webServer> 
0

的Azure存儲庫包括異步方法,你應該把這些優勢。而不是用Task.Run包裝你的控制器方法,你可以使用ASP.NET MVC's built-in async-capabilities

因此,首先,使控制器的異步方法:

public async Task<ContentResult> UploadPhotoFromFileAsync... 

然後刪除所有Task.Runs。

最後,調用Azure存儲庫的異步方法:

var blob = blobContainer.GetBlockBlobReference(blobName); 
await blob.UploadFromStreamAsync(file.InputStream); 
+0

嗨邁克爾,我試過這個,但它仍然鎖定第一次運行。我做了一些閱讀,看起來似乎陷入僵局。任何想法爲什麼? – Andrew