2015-12-30 11 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