异步方法在多个图像上传时首先失败 运行
Async method fails first run on multiple image upload
我有一个摄影师可以上传照片的网站。该站点托管在共享的 Azure Web 应用程序上,照片和照片的缩略图上传到 Azure Blob 存储,并将记录写入数据库。摄影师一次最多可以上传 700mb 的照片。
我的问题
我有一个同步上传方法,A) 花了很长时间 运行 和 B) 失败并显示 "There is not enough space on disk" 错误消息。我猜这是因为 Azure 共享 Web 应用程序的临时文件夹限制为 200mb。
我试图实现一个异步方法来帮助加快上传速度,但它成功地完成了第一张照片(即存在 blob 和数据库记录),然后它似乎只是挂起。这是我第一次尝试编写异步方法。
我也不知道如何解决临时文件夹大小问题。
我的调用方式
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);
}
});
}
Azure 存储库包括 Async-methods,您应该利用它们。而不是用 Task.Run 包装你的控制器方法,你可以使用 ASP.NET MVC's built-in async-capabilities.
所以,首先,使控制器的方法异步:
public async Task<ContentResult> UploadPhotoFromFileAsync...
然后删除所有 Task.Run。
最后,调用 Azure 存储库的 async-methods:
var blob = blobContainer.GetBlockBlobReference(blobName);
await blob.UploadFromStreamAsync(file.InputStream);
问题实际上是由 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>
我有一个摄影师可以上传照片的网站。该站点托管在共享的 Azure Web 应用程序上,照片和照片的缩略图上传到 Azure Blob 存储,并将记录写入数据库。摄影师一次最多可以上传 700mb 的照片。
我的问题
我有一个同步上传方法,A) 花了很长时间 运行 和 B) 失败并显示 "There is not enough space on disk" 错误消息。我猜这是因为 Azure 共享 Web 应用程序的临时文件夹限制为 200mb。
我试图实现一个异步方法来帮助加快上传速度,但它成功地完成了第一张照片(即存在 blob 和数据库记录),然后它似乎只是挂起。这是我第一次尝试编写异步方法。
我也不知道如何解决临时文件夹大小问题。
我的调用方式
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);
}
});
}
Azure 存储库包括 Async-methods,您应该利用它们。而不是用 Task.Run 包装你的控制器方法,你可以使用 ASP.NET MVC's built-in async-capabilities.
所以,首先,使控制器的方法异步:
public async Task<ContentResult> UploadPhotoFromFileAsync...
然后删除所有 Task.Run。
最后,调用 Azure 存储库的 async-methods:
var blob = blobContainer.GetBlockBlobReference(blobName);
await blob.UploadFromStreamAsync(file.InputStream);
问题实际上是由 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>