2009-07-18 33 views
5

Estoy cargando archivos de gran tamaño a un servidor ASP.NET utilizando un control HTML estándar <input> publicando datos de varias partes. Esta es una aplicación ASP.NET MVC.¿Por qué HttpPostedFile no funciona como se anuncia y las descargas del búfer en el disco en lugar de en la memoria?

Según MSDN, los HttpPostedFile buffers de clase en el disco fuera de la caja:

"los archivos se cargan en MIME formato multipart/form-data Por por defecto, todas las solicitudes, incluyendo la forma campos. y los archivos cargados, más grandes que 256 KB se almacenan en el búfer, más bien que en la memoria del servidor ".

Supongo que esto significa que cuando accedo HttpPostedFileBase en mi controlador, que cuando accedo InputStream propiedad del HttpPostedFileBase 's, puedo escribir el buffer de archivo en algún lugar sin tener que preocuparse por el servidor que ejecuta fuera de la memoria, lo cual es obviamente una solución inviable.

Aquí hay un poco de pseudocódigo de cómo manejo cada uno de los archivos entrantes de HttpPostedFileBase.

for(var i = 0; i< Request.Files.Count;i++) 
{ 
    var fileBase = Request.Files[i]; 
    if (fileBase.ContentLength == 0) 
    { 
     continue; 
    } 

    // One thread per file 
    ThreadPool.QueueUserWorkItem(state => 
    { 
     // Read from fileBase.InputStream 
    }, 
    null); 
} 

bloque httpRuntime de mi web.config se ve así:

<httpRuntime 
    executionTimeout="1200" 
    requestLengthDiskThreshold="2097151" 
    maxRequestLength="2097151" 
    useFullyQualifiedRedirectUrl="false" 
    minFreeThreads="8" 
    minLocalRequestFreeThreads="4" 
    appRequestQueueLimit="100" /> 

Mis trabajos de implementación, varios archivos se cargan como se esperaba, con la excepción de que se consume la misma cantidad de memoria necesaria para amortiguar toda la carga útil por el servidor. Tengo que suponer que InputStream está almacenando todo. Cuando cargo más archivos de los que tengo en la memoria, se bloquea de forma predecible con un OutOfMemoryException. Aquí hay una imagen del pico de memoria al cargar un archivo de 800mb.

alt text

Sé que podría utilizar un widget Flash/Silverlight o escribir una costumbre HttpModule para interceptar las subidas y manejarlos a mí mismo, pero el requisito actual podría funcionar sin problemas si HttpPostedFile hicieron lo MSDN dice que lo hace (o yo lo estoy haciendo mal).

Respuesta

5

¿por qué se establece

requestLengthDiskThreshold="2097151" 

en la configuración? ¿Eso no obliga al servidor a mantener todas las cargas en la memoria RAM en lugar de almacenarlas en el disco?

+0

Por supuesto. Estaba depurando otro aspecto de la carga y lo configuré sin pensar. Al establecerlo en 256kb mantiene la memoria del servidor donde pertenece. ¡Gracias! –

+0

@DanielCrenna configurándolo a 256 kb ¿se puede cargar con éxito? Por favor responda. –

Cuestiones relacionadas