异步方法在多个图像上载时首次运行失败

时间:2015-12-30 04:45:22

标签: c# asp.net-mvc azure asyncfileupload

我有一个摄影师可以上传照片的网站。该网站托管在共享的azure Web应用程序上,照片的照片和缩略图将上传到Azure Blob存储,并将记录写入数据库。摄影师一次最多可以上传700张照片。

我的问题

我有一个用于上传的同步方法,A)需要很长时间才能运行,而B)使用&#34失败;磁盘上没有足够的空间"错误信息。我猜这是因为Azure共享Web应用程序的临时文件夹限制为200mb。

我尝试实现一个异步方法来帮助加快上传速度,但它成功完成了第一张照片(即blob和db记录存在),然后它似乎只是挂起。这是我编写异步方法的第一次尝试。

我也不知道如何修复临时文件夹大小问题。

我的呼叫方法

    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);
            }
        });
    }

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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>