新建的FileStream立即关闭

问题描述 投票:0回答:1

我有一个长期运行的处理进口的流程。导入很长一段时间都很好,但突然突然出现异常,即使我没有改变任何东西。导入文件使用库

NPOI

一个进程将文件复制到文件夹:

System.IO.File.Copy(fileNameDownload, path);

几分钟后,另一个进程尝试访问它:

using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
  var xlsxBook = new XSSFWorkbook(fs); // suddenly threw exception
  var xlsBook = new HSSFWorkbook(fs);
}

但是访问这个文件流突然抛出了一个新的异常:

Cannot access a closed file
at System.IO.__Error.FileNotOpen()
   at System.IO.FileStream.Read(Byte[] array, Int32 offset, Int32 count)
   at NPOI.Util.IOUtils.ReadFully(Stream stream, Byte[] b, Int32 off, Int32 len) in C:\github\npoi\main\Util\IOUtils.cs:line 179
   at NPOI.POIFS.FileSystem.NPOIFSFileSystem..ctor(Stream stream) in C:\github\npoi\main\POIFS\FileSystem\NPOIFSFileSystem.cs:line 291

重启服务后,错误消失。不过,我想追根究底,以避免将来发生这种情况。

c# exception windows-services filestream npoi
1个回答
0
投票

异常看起来来自后台线程。我的猜测是,工作簿使用后台线程来异步保存更改,并且由于底层流已被处理,一些旧对象失败了。

如果工作簿实现了 IDisposable,则需要对其进行处置(除非文档指定不同)。通常喜欢

using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using var xlsxBook = new XSSFWorkbook(fs);
using var xlsBook = new HSSFWorkbook(fs);

如果您要归还作业簿,则需要更多考虑。

对象通常要求任何传递的流在对象的生命周期内都处于活动状态。对象可能也拥有流的所有权,使得处理文件流变得不必要,并且可能适得其反。通常带有“leaveOpen”标志来选择退出。这应该都在文档中指定。

如果文档不清楚,最好保守一点,并按照与创建相反的顺序处理所有内容。例如通过使用包装器:

public class MyWrapper(FileStream Fs, XSSFWorkbook XlsxBook, HSSFWorkbook XlsBook) : IDisposable{

    public void Dispose(){
         XlsBook.Dispose();
         XlsxBook.Dispose();
         Fs.Dispose();         
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.