2017-01-31 51 views
1

Я откровенно тупик. Это не соответствует моему опыту.Как увеличить максимальный размер загрузки в приложении MVC?

У меня есть программа C# MVC, которая генерирует zip-файл в MemoryStream для загрузки. Метод действия вызывается нажатием кнопки JavaScript.

Единственная проблема заключается в том, что в некоторых случаях потенциальный размер файла может легко превышать один Gig и из моего чтения, что является общей проблемой. Я попытался увеличить максимально допустимую длину контента до 3000000000 в фильтрации запросов на IIS (IIS8). Я попытался добавить requestLimits maxAllowedContentLength в свой web.config. Я даже пытался разбить почтовый ящик несколькими вызовами метода действия (без успеха), хотя мне еще нужно получить подтверждение/опровержение, что это даже возможно.

Есть ли какие-либо настройки в IIS или моем web.config, которые я мог бы игнорировать? Может ли это быть проблемой сетевой компании, не разрешимой на уровне разработчика приложений?

+0

Хотя вы не указали точную проблему, с которой вы сталкиваетесь, на основе тегов вашего вопроса, я предполагаю, что у вас закончилась нехватка памяти. Для этого нет решения, кроме того, что на вашем сервере больше места. Не существует встроенного ограничения на загрузку, но если вы создаете что-то в памяти, очевидно, оно не может быть больше, чем доступная память системы. –

+0

Стоит отметить, что вам также потребуется учитывать несколько запросов. Например, если вы создаете файл размером 1 ГБ, добавление 1 ГБ дополнительной памяти помогает только одному запросу. Если два человека пытаются получить доступ к тому же действию, которое создает этот 1GB-файл, тогда вам понадобится 2 ГБ ОЗУ для удовлетворения обоих запросов. Кэширование созданного файла в файловой системе помогло бы, поскольку вам понадобится только память для первоначального создания, но вы должны убедиться, что у вас много запаса выше среднего размера файла. –

+0

Я запросил больше памяти у руководства (но я не задерживаю дыхание ...) У него уже 8 концертов. – user2996466

ответ

0

Хорошо, так что трудно объяснить большие понятия в 400 символов или меньше, поэтому я думаю, что я просто вызываю больше путаницы в разделе комментариев. Кроме того, я думаю, что мы достаточно близко относимся к «ответ», как вы, вероятно, получите.

Конструктор по умолчанию MemoryStream по существу устанавливает начальный размер равным 0. В действительности, начальный размер устанавливается где-то около 256, но поскольку начальный размер является главным образом ориентиром, и на самом деле он не утверждает это пространство до тех пор, пока его необходимо, оно начинается с 0.

Каждый раз, когда вы пишете в поток, он проверяет, сколько написано в сравнении с остальным размером массива буфера. Если он не может соответствовать записи, он создает новый больший буферный массив и копирует в него старый буферный массив. Таким образом, установка начального размера может помочь в том, что вы начинаете с большего массива начального буфера, и вам может не понадобиться вырастить этот буфер. У вас есть может иметь больше шансов получить непрерывный блок памяти, который я объясню важность немного, но это на самом деле тоже работает против вас. Если вам нужен только 1 МБ для файла, но вы инициализируетесь с 100 МБ и, то нет 100 Мб непрерывной памяти, вы получите OutOfMemoryException, хотя может быть 1 МБ непрерывной памяти.

Независимо от того, инициализированы ли вы или нет, остаются некоторые непреложные факты. Во-первых, MemoryStream требует непрерывной памяти. Даже если у вас есть технически доступная память в системе, возможно, у вас может не быть больших блоков доступной памяти. Другими словами, если у вас есть 4 ГБ, но все фрагментировано, даже попытка создать поток 1 ГБ в памяти может потерпеть неудачу, просто потому, что он не может зарезервировать 1 ГБ смежных памяти. Очевидно, чем больше файл, который вы связываете для создания в памяти, тем больше вероятность того, что вы столкнетесь с этой проблемой. По этой причине я бы сказал, что вам не повезло, не увеличивая объем оперативной памяти. С 8 ГБ и, вероятно, только 4-6 ГБ, фактически доступными для IIS, а затем разделить между рабочими процессами и потоками, вероятность того, что вы сможете требовать 25% или около того доступной ОЗУ в качестве непрерывного пространства, маловероятна.

Следующий непреложный факт может быть или не быть релевантным, но поскольку вы не указали, я расскажу об этом. Если ваше веб-приложение развернуто как 32-разрядное, у вас будет жесткий предел в 2 ГБ для любого объекта, то есть MemoryStream никогда не сможет разместить более 2 ГБ (на самом деле около 1,3-1,6 ГБ.NET-код потребляет часть этого адресного пространства), и любая попытка сделать это приведет к OutOfMemoryException, даже если у вас было какое-то нелепое количество оперативной памяти в системе, например, 1TB +. Если ваше приложение является 64-битным, это, скорее всего, проблема, поскольку вы можете адресовать тонну больше памяти, предполагая, что она скомпилирована должным образом. Вы, должно быть, очень пытаетесь это испортить, так что с вами все будет в порядке.

И, наконец, многократная запись может также вызвать проблему. Как я уже говорил ранее, массив буфера изменяет размер (при необходимости) в ответ на запись. Каждый раз, когда он изменяет размер, новый буферный массив должен также быть в состоянии разместить в смежном адресном пространстве. В результате множественные изменения размеров могут привести к тому, что вы столкнетесь с OutOfMemoryException, которые вы бы не ударили, если бы вы написали все данные с самого начала. Здесь инициализация MemoryStream может быть полезна, но, как я уже говорил, это также обоюдоострый меч, так как ваш начальный размер буфера может быть слишком велик, чтобы начать, и вы получите исключение, где у вас может не быть одного позволяя ему расти органично. Длинные и короткие, старайтесь писать все в поток за один раз, а не по частям.

+0

Чтобы уточнить, приложение скомпилировано с помощью Target = Any CPU. Однако сервер, на котором он работает, составляет 64 бит, а пул приложений, в котором он запущен, имеет Enable 32 Bit Applications = False. Поэтому я думаю, что я в порядке. Пожалуйста, уточните, что нужно писать все в поток. Процесс по существу представляет собой цикл, который добавляет по одному файлу за раз. Не уверен, что я вижу другой способ сделать это. – user2996466

+0

Полная неудача пока. Мой босс поднял память до 16Gig. Затем я попробовал свою программу как с иничизацией размера MemoryStream, так и без него. Одна и та же «арифметическая» ошибка. – user2996466

+0

Другое: первое сообщение об ошибке в трассировке стека: [HttpException (0x80004005): Произошла ошибка при общении с удаленным хостом. Код ошибки: 0x80070216.] System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError (результат Int32, Boolean throwOnDisconnect) IIS7? На сервере работает IIS8. – user2996466

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

  • Нет связанных вопросов^_^