我正在努力解决一个问题,即我一直在砸墙头。我想要完成的是从存储在Web服务器上的文件夹中的Excel文件中读取表名(工作表名称)。我将使用这些工作表名称来确定我将从中读取值的工作表。我遇到的问题是用户随机遇到文件被asp.net进程锁定的问题,然后不同会话中的其他用户和不同文件都无法访问文件夹上的文件。文件被锁定后,我无法从数据文件夹中删除该文件,因为它正由另一个进程使用。
唯一可以释放文件夹的是进行应用程序池刷新。我在X64中运行我的应用程序池以容纳XLSX和XLS文件。我让服务器团队运行procmon工具,看看哪些进程锁定了文件夹并且没有得到有用的信息。
我将我的文件位置连接到using语句中,以确保正确处理。当文件被锁定或者没有退出using语句的进程时,它不允许用户在同一位置创建与另一个完全唯一且不同的文件的新连接。用户可以将文件写入文件夹位置并删除文件,但无法执行以下代码中的conn.Open。用户无法导航到文件夹位置并删除该进程锁定的文件。正如我之前所说,这种情况随机发生,很难再创造。我已经查看该文件夹是否正在运行索引或备份作业,但它们没有。
我试图在处理过程中放置一个锁定对象,这样当我从文件中提取值时,没有其他进程可以访问该文件。棘手的部分是,在应用程序池刷新后,我无法让文件锁定发生一段时间....它就像是用完了连接对象,或者应用程序池陷入了2个进程尝试同时访问文件的位置或者其他的东西。我们的应用程序池每24小时刷新一次,因此它会自动释放对象,我们可以删除文件,也可以从文件夹上的其他Excel工作表中提取数据。但是如果我们看到这个锁定的流程问题,我们就无法在白天随机刷新应用池。
public const string ExcelConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1;ApplicationIntent=ReadOnly;ReadOnly=True;\"";
DataTable dt = ExecuteDataTable(connectionString, String.Format("SELECT * FROM [{0}] ", sheetName.Trim()));
string connectionString = DataServices.ExcelConnection;
string fileConnection = string.Format(connectionString, mappedPath.Trim());
Object lockObject = new Object();
lock (lockObject)
{
// Setup the connection to the file
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(fileConnection))
{
if (File.Exists(mappedPath))
{
try
{
conn.Open();
this.sheetNamesFromFile = conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);
if (this.sheetNamesFromFile.Rows.Count > 0)
{
this.sheetName = RetrieveSheetName(this.sheetNamesFromFile, fileName);
ViewState.Add("SheetName", this.sheetName.ToString().Trim());
if (!string.IsNullOrEmpty(this.sheetName))
{
this.massUploadExcelData = DataServices.GetExcelData(conn.ConnectionString, this.sheetName, fileName); // getexcledata has the following code to grab all data from the sheet name - DataTable dt = ExecuteDataTable(connectionString, String.Format("SELECT * FROM [{0}] ", sheetName.Trim()));
if (this.massUploadExcelData.Rows.Count < 1)
{
this.ShowMessageOnSubmit(this.Labels.GetLabel("norecordsintable"), false);
}
}
else
{
this.ShowMessageOnSubmit(this.Labels.GetLabel("uploadnosheet"), false);
}
}
}
catch (System.Data.OleDb.OleDbException dataExp)
{
EventLogging.LogError("An error has occurred when saving a mass upload file, the file the user is using could have corrupt data : Mapped path = " + mappedPath + " File Path and Name = " + fileName, dataExp);
this.error = "An error has occured when trying to load a mass upload file, user might have corrupt data. exception = " + dataExp;
return string.Empty;
}
}
else
{
EventLogging.LogError("The file does not exist that is trying to be accessed in the application, mapped path - " + mappedPath);
}
}
// Delete the file in data folder, since we already have the datatable of the data and sheet name
if (File.Exists(mappedPath))
{
DeleteFile(mappedPath);
}
}
任何想法和方向都会被欣赏。