我对 MVC 和 .NET 还很陌生,我遇到了第一个问题,我已经坚持了 3 天。我为这篇冗长的帖子道歉。
我正在处理的项目的一部分要求用户能够选择 XLS 或 XLSX 文件并上传它,以便应用程序可以导入数据。上传的文件很可能有超过 20,000 行数据。
我有包含 5000、10000 和 20000 行的测试文件。当我在本地机器上运行我的应用程序(使用 Visual Studio 2010)时,所有这些文件都会保存到网络共享并处理得很好。没有错误。但是,当我将应用程序部署到我们的开发服务器时,我在5 分钟后收到一个错误,即无法访问 10k 和 20k 文件,因为它正在被另一个进程使用。
错误消息:该进程无法访问文件“已删除路径\TestBook-10k-rows.xlsx 的这一部分”,因为它正被另一个进程使用。
堆栈跟踪:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode)
at System.Web.HttpPostedFile.SaveAs(String filename)
at System.Web.HttpPostedFileWrapper.SaveAs(String filename)
at edtStar.Controllers.TableController.Import(HttpPostedFileBase UploadFile, FormCollection collection) in <removed this part of the path>\TableController.cs:line 392
10000 行文件的大小为 304KB,我在 web.config 中设置了如下长度限制:
<httpRuntime
maxRequestLength="4096"
requestLengthDiskThreshold="1024"/>
我在 5 分钟左右找不到任何特别的东西,但是在我开始上传 5 分钟后它总是返回错误。
我已经用 Chrome 和 IE 试过了。两者都通过 localhost 工作,都不能通过我们的 dotnet 应用服务器工作。
堆栈跟踪说它在 SaveAs() 方法上爆炸了,但我可以在网络共享位置看到文件并且大小匹配。
保存文件后,我必须读取它并将数据返回到新视图。在将数据返回到视图之前,对数据进行了相当多的处理,这是我希望等待 5 分钟或更长时间的地方。读完文件后,我关闭连接并从网络共享中删除文件。在我收到异常后不久,该文件也被删除。当我开始每次上传时,该文件不存在。
我是目前唯一使用此应用程序的人,因为它仍在开发中。在我进行测试时,我不相信其他人正在访问网络共享上保存的副本。我可以始终如一地重现这个问题,但我不知道它为什么会发生。
有没有人看到过这样的事情或对我有什么建议?我的猜测是我们的应用服务器上有一个设置,但我无法查明它。
谢谢!
编辑:
这是处理文件上传的代码。
// Validate, save, and read the selected file.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Import(HttpPostedFileBase UploadFile, FormCollection collection)
{
// Do some initial file validation - removed
string filePath = Path.Combine(EDTConstants.NETWORK_SHARE_PATH, Path.GetFileName(UploadFile.FileName));
try
{
// Do some validation on the file that was uploaded.
if (UploadFile == null)
{
// return an error here - there was no file selected.
}
if (UploadFile.ContentLength == 0)
{
// return an error here - the file is empty.
}
if (!filePath.ToUpper().EndsWith("XLS") && !filePath.ToUpper().EndsWith("XLSX"))
{
// return an error here - the file extension is not supported.
}
// Things are good so far. Save the file so we can read from it.
UploadFile.SaveAs(filePath);
DataSet fileDS = new DataSet();
string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=\"Excel 12.0;HDR=YES;\"";
using (OleDbConnection conn = new OleDbConnection(connString))
{
conn.Open();
using (DataTable dtExcel = conn.GetSchema("Tables"))
{
// ... a bunch of code removed ...
}
conn.Close();
}
CloseFile(filePath);
}
catch (Exception e)
{
// Unexpected error
EDTUtils.LogErrorMessage(EDTConstants.TABLE_IMPORT, User.Identity.Name, e);
ViewData[EDTConstants.SSN_VD_ERROR_MSG] = EDTConstants.EM_UNEXPECTED + System.Environment.NewLine + e.Message;
ViewData[EDTConstants.VIEWDATA_FILE] = UploadFile.FileName;
CloseFile(filePath);
return View(tab);
}
// Closes a file - logs errors but does not throw any exceptions.
private void CloseFile(string filePath)
{
try
{
System.IO.File.Delete(filePath);
}
catch (IOException ioe)
{
EDTUtils.LogErrorMessage(EDTConstants.TABLE_IMPORT, User.Identity.Name, ioe);
}
}
我确实看到记录了相同的错误,一次是在执行 SaveAs() 时,然后是在执行 Delete 时。奇怪的是,文件确实消失了。几乎就像应用服务器有另一个线程在此过程中尝试做某事,而这不会发生在 localhost 上。
编辑
在我更改 executionTimeout 值后,我注意到 Chrome 在 5 分钟标记处说“Uploading 79%...”,然后文件在网络共享上消失了,然后重新出现,然后一两分钟后,Chrome 说页面不可用,带有“错误代码:ERR_INVALID_RESPONSE”。该文件尚未从网络共享中删除。在 IE 中,我被要求在 5 分钟后再次登录该应用程序。