MVC 大文件上传 运行 内存不足
MVC Large File Uploads Running Out of Memory
.Net 4.5.1 - MVC5 - EF6
要求是允许上传大文件(<200MB)。我有一个带有 HttpPostedFileBase 的 ViewModel。我将其输入流设置为数据库实体非映射流 属性。然后将其发送到存储库,我将“复制流”保存到 SQLFileStream。这一切都有效。
但是...在大约 ~4 个大型上传后进行调试时,我收到 System.OutOfMemory 异常。我可以看到 HttpRawUploadedContent 正在继续增长,并将不再使用的 PostedFiles 保留在内存中。我究竟做错了什么?我怎样才能把这些东西处理掉?有没有更好的办法?任何指导表示赞赏。
AttachmentViewModel.cs
public class AttachmentViewModel
{
#region Public Properties
public int Id { get; set; }
public string FileName { get; set; }
[MaxFileSize]
public HttpPostedFileBase PostedFile { get; set; }
#endregion Public Properties
}
未映射 属性 数据库 FileEnitity
[NotMapped]
public Stream PostedStream { get; set; }
FileRepository.cs 添加方法
public override T Add(T entity)
{
base.Add(entity);
//Save to generate ID
_ctx.SaveChanges();
using (var tx = new TransactionScope())
{
try
{
var id = entity.Id;
var rowData =
_ctx.Database.SqlQuery<FileStreamData>(FileRowSelect, new SqlParameter("id", id))
.First();
using (var dest = new SqlFileStream(rowData.Path, rowData.Transaction, FileAccess.Write))
{
//Copy the posted stream to the SQLFileStream
entity.PostedStream.CopyTo(dest);
}
tx.Complete();
}
catch
{
//Error Uploading Stream Revert
base.Remove(entity);
_ctx.SaveChanges();
throw;
}
}
return entity;
}
内存截图
感谢@kad1r,他为我指明了正确的方向。 (即:不是 Http)
原来我不明白 requestLengthDiskThreshold 的实际作用。
The RequestLengthDiskThreshold should be less than the
MaxRequestLength value and indicates at what point or 'threashold'
that the request will begin to be buffered transparently onto disk.
http://forums.asp.net/t/1680176.aspx?httpRuntime+maxRequestLength+vs+requestLengthDiskThreshold+
通过增加此值,IIS 将更多请求存储在内存中而不是磁盘中。
.Net 4.5.1 - MVC5 - EF6
要求是允许上传大文件(<200MB)。我有一个带有 HttpPostedFileBase 的 ViewModel。我将其输入流设置为数据库实体非映射流 属性。然后将其发送到存储库,我将“复制流”保存到 SQLFileStream。这一切都有效。
但是...在大约 ~4 个大型上传后进行调试时,我收到 System.OutOfMemory 异常。我可以看到 HttpRawUploadedContent 正在继续增长,并将不再使用的 PostedFiles 保留在内存中。我究竟做错了什么?我怎样才能把这些东西处理掉?有没有更好的办法?任何指导表示赞赏。
AttachmentViewModel.cs
public class AttachmentViewModel
{
#region Public Properties
public int Id { get; set; }
public string FileName { get; set; }
[MaxFileSize]
public HttpPostedFileBase PostedFile { get; set; }
#endregion Public Properties
}
未映射 属性 数据库 FileEnitity
[NotMapped]
public Stream PostedStream { get; set; }
FileRepository.cs 添加方法
public override T Add(T entity)
{
base.Add(entity);
//Save to generate ID
_ctx.SaveChanges();
using (var tx = new TransactionScope())
{
try
{
var id = entity.Id;
var rowData =
_ctx.Database.SqlQuery<FileStreamData>(FileRowSelect, new SqlParameter("id", id))
.First();
using (var dest = new SqlFileStream(rowData.Path, rowData.Transaction, FileAccess.Write))
{
//Copy the posted stream to the SQLFileStream
entity.PostedStream.CopyTo(dest);
}
tx.Complete();
}
catch
{
//Error Uploading Stream Revert
base.Remove(entity);
_ctx.SaveChanges();
throw;
}
}
return entity;
}
内存截图
感谢@kad1r,他为我指明了正确的方向。 (即:不是 Http)
原来我不明白 requestLengthDiskThreshold 的实际作用。
The RequestLengthDiskThreshold should be less than the MaxRequestLength value and indicates at what point or 'threashold' that the request will begin to be buffered transparently onto disk.
http://forums.asp.net/t/1680176.aspx?httpRuntime+maxRequestLength+vs+requestLengthDiskThreshold+
通过增加此值,IIS 将更多请求存储在内存中而不是磁盘中。