【问题标题】:MVC Large File Uploads Running Out of MemoryMVC 大文件上传内存不足
【发布时间】: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


【解决方案1】:

应该归功于@kad1r,因为他为我指明了正确的方向。 (即:不是Http)

原来我不明白 requestLengthDiskThreshold 的实际作用。

RequestLengthDiskThreshold 应该小于 MaxRequestLength 值并指示在什么点或“阈值” 请求将开始透明地缓冲到磁盘上。

http://forums.asp.net/t/1680176.aspx?httpRuntime+maxRequestLength+vs+requestLengthDiskThreshold+

通过增加此值,IIS 将更多的请求存储在内存中而不是磁盘中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 2012-02-15
    相关资源
    最近更新 更多