2013-06-03 3 views
2

Я получаю эту ошибку при загрузке файла с 84 МБ (см. Ниже), но когда я загружаю файл размером 60 МБ, он работает нормально. Это происходит только на нашей 32-битной памяти VM объемом до 4 ГБ. На моей 64-битной памяти VM с памятью 8 ГБ он отлично работает даже с 130 МБ-файлом.System.OutOfMemoryException: Исключение при загрузке файла

System.OutOfMemoryException: Исключение типа 'System.OutOfMemoryException' был брошен. в System.IO.BinaryReader.ReadBytes (кол Int32) в CustWeb.Controllers.DownloadsController.Create (Download дл, HttpPostedFileBase файл) в C: \ ... \ CustWeb \ Контроллеры \ DownloadsController.cs: линия 72

Я наблюдал за памятью в диспетчере задач, хотя он не превышает 74% во время всего процесса загрузки.

Это приложение MVC 4 на платформе .NET .NET.

У меня есть максимальные настройки в моем web.config при работе с загрузкой файлов.

<httpRuntime requestValidationMode="4.5" targetFramework="4.5" maxRequestLength="2147483647" executionTimeout="84000" /> 

...

<security> 
    <requestFiltering> 
     <requestLimits maxAllowedContentLength="2147482624" /> 
    </requestFiltering> 
</security> 

UPDATE Добавление кода в соответствии с просьбой:

public ActionResult Create(Download dl, HttpPostedFileBase file) 
    { 
     try 
     { 
      using (var binaryReader = new BinaryReader(file.InputStream)) 
      { 
       dl.FileBytes = binaryReader.ReadBytes(file.ContentLength); 
      } 
      dl.FileContentType = file.ContentType; 
      dl.FileName = file.FileName; 
      dl.Insert(); 
      Success("<strong>" + dl.Label + "</strong> created and uploaded successfully."); 
      return RedirectToAction("Index"); 
     } 
     catch (Exception ex) 
     { 
      SelectList list = new SelectList(new DownloadType().GetDownloadTypes(), "ID", "Name"); 
      ViewBag.DownloadTypeList = list; 
      Error(ex.ToString()); 
      return View(dl); 
     } 
    } 
+0

Покажите нам свой код. – SLaks

+0

Использование 'BinaryReader' здесь неверно. – leppie

+0

@SLaks - добавлен мой код по вашему желанию. – RichC

ответ

0

Я изменил его из потока в файл. Сохраняет и предотвращает ошибку памяти.

public ActionResult Create(Download dl, HttpPostedFileBase file) 
    { 
     try 
     { 
      string tempFile = Path.Combine(Server.MapPath("~/App_Data/"), string.Format("{0}_{1}",Guid.NewGuid().ToString(), Path.GetFileName(file.FileName))); 
      file.SaveAs(tempFile); 
      dl.FileBytes = System.IO.File.ReadAllBytes(tempFile); 
      dl.FileContentType = file.ContentType; 
      dl.FileName = file.FileName; 
      dl.Insert(); 
      System.IO.File.Delete(tempFile); 
      Success("<strong>" + dl.Label + "</strong> created and uploaded successfully."); 
      return RedirectToAction("Index"); 
     } 
     catch (Exception ex) 
     { 
      SelectList list = new SelectList(new DownloadType().GetDownloadTypes(), "ID", "Name"); 
      ViewBag.DownloadTypeList = list; 
      Error(ex.ToString()); 
      return View(dl); 
     } 
    } 
+0

Я все же иногда получаю ошибки памяти, но при изменении этого метода определенно улучшен (в два раза) размер файла, который я могу загрузить. Думаю, мне придется увеличить реальную ОЗУ, чтобы сделать лучше, чем файл размером 160 МБ. – RichC

+0

После некоторого чтения по этому вопросу. Моя проблема заключается не в загрузке файла, а в readAllBytes, прежде чем сохранить его в базе данных.Также похоже, что если я собираюсь сохранить файлы размером 200 Мбайт +, я должен вместо этого сохранить их в файловой системе и сохранить ссылку на БД. – RichC

3

По умолчанию ASP.NET допускается 60% доступной памяти - проверить memoryLimit in processModel in machine.config. Вы можете изменить это значение, скажем, на 80%, чтобы предоставить ASP.NET больше места, но это не рекомендуется. Рассмотрите другие варианты, такие как загрузка файла в куски и т. Д.

+0

Вау - как вы загружаете файлы в куски? – RichC

+0

Существуют разные способы использования HTTP-модулей, например: http://dotnetslackers.com/Community/blogs/haissam/archive/2008/09/12/upload-large-files-in-asp-net-using-httpmodule.aspx к использованию сторонних элементов управления, например http://www.plupload.com/. Но даже до этого попробуйте сыграть с атрибутом 'requestLengthDiskThreshold' раздела' httpRuntime' в файле web.config, который вы указали выше. Он контролирует размер загруженного файла, который сервер может хранить в памяти, прежде чем кэшировать его на диск. –

+0

По умолчанию используется 256 байт, чтобы предотвратить использование слишком большого объема памяти. похоже, что увеличение будет использовать еще больше памяти и ухудшит проблему, нет? – RichC

Смежные вопросы