【发布时间】:2015-05-16 05:42:39
【问题描述】:
.Net 4.5.1 - MVC5 - EF6
要求是允许大文件上传(
但是...在大约 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
}
数据库文件实体上的非映射属性
[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;
}
内存截图
【问题讨论】:
-
您需要寻找其他解决方案。 Web 服务器不是为处理这种类型的上传大小而设计的。老实说,HTTP 作为一种协议并不是为了处理这种类型的上传大小而设计的。
-
web.config 上有 requestLengthDiskThreshold 吗?
-
请记住,HTTP 作为规范是在 90 年代初创建的,当时甚至还没有“网络”之类的东西。 HTTP 旨在快速有效地进行 短 通信。它既不是为上传数百兆数据的大规模扩展通信会话而设计的,也无意用于上传。这只是一个简单的事实。这与任何事情有什么关系?这是您尝试用来上传文件的协议。为什么你认为 FTP 协议存在?
-
对于像 YouTube 这样的网站。好吧,他们必须使用他们必须使用的东西。无论好坏,这意味着 HTTP。但是,他们和您之间的一个区别是大量 的钱可以用来解决问题。他们可以购买具有 TB 级 RAM、大型超高速硬盘驱动器、CDN 存储等的服务器。他们还多次通过直连管道,这样他们的数据中心和像 Level3 这样的主要管道供应商之间没有互换。这使得在一个不是为它设计的协议上可以做很多事情。
-
您仍然没有提供任何证据证明 Http 不是为大文件上传而设计的。您甚至提出了 Ftp 的事实表明您不了解问题所在。在这种情况下,Ftp 绝对没有任何收获。如果我希望用户能够恢复上传,我会使用 Ftp。使用的“Freaking Protocol”与问题或问题无关。该问题与 .Net、IIS 或我的代码中的内存问题有关。我说的是上传一个小于 200MB 的 ~4 个文件; youtube 有数百万次上传,最大 2GB。显然,“Freaking Protocol”可以满足我的需求。
标签: c# asp.net-mvc memory file-upload sqlfilestream