我试图逐行处理一个长度为几百KB的文件,但是当我尝试上传长度超过80KB的文件时,我得到一个例外:
Object Disposted Exception: Cannot access a closed file.
将文件上传到控制器并传递给异步任务,如下所示:
public JsonResult Index(HttpPostedFileBase csvFile)
{
AsyncManager.OutstandingOperations.Increment();
System.Threading.Tasks.Task.Factory.StartNew(() => {
ProcessFile(csvFile);
AsyncManager.OutstandingOperations.Decrement();
});
return Json(new {fileId = fileId});
}
然后处理文件
public static void ProcessFile(HttpPostedFileBase csvFile) {
Int32 lineCount = 0;
StreamReader lineCounter = new StreamReader(csvFile.InputStream);
while (lineCounter.ReadLine() != null) { // exception occurs here with lineCount still 0
lineCount += 1;
}
//Continue processing
据我所知,默认情况下它不会接受大于80KB的文件,但我在web.config中添加了以下行:
<system.web>
<httpRuntime executionTimeout="3600" maxRequestLength="30000000" requestLengthDiskThreshold="30000000" useFullyQualifiedRedirectUrl="false" />
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="30000000" />
</requestFiltering>
</security>
</system.webServer>
但这不会改变结果。文件一直工作到79KB。
我还需要添加其他内容吗?
我的解决方案是将文件本地保存在App_Data中,并传入文件位置而不是实际文件。据我所知,仍然没有理由为什么IIS不接受大于80KB的文件,并且一旦我尝试访问它就失败,而79KB文件运行正常。我没有第三方库,也没有其他进程或代码试图访问该文件
答案 0 :(得分:0)
我有完全相同的问题。我正在扩展Asp.Net CMS Episerver类,并希望通过电子邮件发送文件附件。默认情况下,Episerver会发送用户登录和下载所需的链接。我尝试了从异步调用和任务等待的所有内容。我有非常奇怪的异常,最重要的是这个:无法访问已关闭的文件。我非常确定在访问文件流对象时从未处理过它。
罪魁祸首是web.config中的requestLengthDiskThreshold设置。 requestLengthDiskThreshold的默认大小为80kb(https://msdn.microsoft.com/en-us/library/e1f13641(v=vs.100).aspx)
我更新了web.config,如下所示:
httpRuntime maxRequestLength =“1000000” requestLengthDiskThreshold =“10240”requestValidationMode =“2.0”
然后我的问题就消失了。
答案 1 :(得分:0)
您的问题在于IIS处理文件上传的方式。超过80Kb的所有文件都是cached to disk,并且当您尝试从MVC请求管道之外的线程读取该流时,您将获得该限制。我并不完全确定IIS对线程的确切作用,但如果你试图通过请求线程读取该流,那么你应该没问题,缓存是透明的。但是,只要您尝试在请求线程之外到达该流,就会收到错误。
另请参阅MSDN了解更多信息。具体请参见HttpRuntimeSection.RequestLengthDiskThreshold Property,它定义了在启动磁盘缓冲之前要保留在内存中的数据量 - 默认值为80kb。
解决方案是将文件复制到某处并将文件路径传递给您的线程进行处理。或者将流复制到字节数组并将其传递给您的线程。