Я немного изменил свой код, заставив программу WRITE заблокировать файл перед записью, и ЧИТАТЬ, чтобы обеспечить устойчивость в случае сбоя:
WRITE: используйте FileStream и заблокируйте его перед попыткой записи. Это предотвратит ошибку WRITE
READ: добавлен механизм повторов, реализующий блок try / catch
Модифицированный код:
WRITE
// simply write to a column
var fileLocation = "D:\\Book.xlsx";
FileInfo fi = new FileInfo(fileLocation);
int i = 1;
while (1 == 1) //ALERT: an infinite loop!
{
using (ExcelPackage excelPackage = new ExcelPackage(fi))
{
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets["Sheet1"];
worksheet.Cells[$"A{i}"].Value = "Test " + i.ToString();
using (var fs = new FileStream(fileLocation, FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
{
fs.Lock(0, fs.Length);
excelPackage.SaveAs(fs);
try
{
fs.Unlock(0, fs.Length); // this raises an exception if fs unlocked already by itself
}
catch (IOException ex) when (ex.Message.ToLower().StartsWith("the segment is already unlocked.",
StringComparison.InvariantCultureIgnoreCase))
{
// NOP; just ignore if already unlocked
}
}
i++;
}
}
READ
//simply populate a list reading excel
var fileLocation = "D:\\Book.xlsx";
FileInfo fi = new FileInfo(fileLocation);
List<string> list = new List<string>();
ExcelWorksheet worksheet = null;
int i = 1;
while (1 == 1) //ALERT: an infinite loop!
{
try
{
using (ExcelPackage excelPackage = new ExcelPackage(fi))
{
worksheet = excelPackage.Workbook.Worksheets["Sheet1"];
if (worksheet.Cells[i, 1].Value != null)
{
list.Add(worksheet.Cells[i, 1].Value.ToString());
}
Console.WriteLine(worksheet.Dimension.Rows.ToString()); // just prove that it read
}
}
catch (Exception ex) when (
ex is IOException &&
ex.Message.StartsWith("The process cannot access the file because another process has locked a portion of the file.", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine($"Attempt: {i}");
}
list.Clear();
}
в коде реального приложения я установил предел READ WHILE равным 3, чтобы повторить попытку дважды, если первая попытка чтения не удалась. В моем случае этого более чем достаточно (так как WRITE короткие; добавляются строки за раз), и приложение работает хорошо в течение месяца.