打开文件并与超时异步获取 FileStream

问题描述

对于现实世界的上下文,我正在尝试解决一个自动化过程中一个有点罕见的问题,该过程构建了一个 C# FileStream,如下所示:

using (var file = new FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.Read))
{
    ...

这个过程每天要通过这条线数千次,并且在极少数情况下,无限期地挂在 FileStream 构造函数的某个地方。我怀疑挂起的原因可能是由于某些用户使用了在 Windows 中作为指定路径内的服务运行的备用文件系统进程,但无论如何,我希望能够解决任何问题问题可能是异步打开 FileStream 并在合理的超时时间后中止。我看到有同步 FileStream 读/写的文档,但我找不到任何用于最初获取打开文件的 FileStream 对象的内容。我已经尝试将 FileStream 打开在一个单独的线程以及一个异步任务中,并且我能够检测到操作是否已挂起,这很好,但是如果发生这种情况,我无法中止卡住的线程。特别是,.Net 不再支持 Thread.Abort,而且 CancellationToken 似乎对我也不起作用。所有 API 都希望正在运行的线程正常终止,但我当然无法控制 .Net 库中发生的事情。

解决方法

Windows 中 "0d275816-7a1d-4847-884d-b5c67f473973" "106004df-6d49-450e-a180-e5bfa1fef9b3" "200a2bc4-feeb-4ab5-a4c1-3cc3752fe50e" "956041d5-49af-4409-a2b4-67c1cf2bc433" API 的一个基本问题是,实际打开文件是同步运行的,并且没有超时。

确实存在CancelSynchronousIo,要使用它,您需要向它传递一个实际的线程句柄,因此您需要在另一个线程上运行文件打开,而不是任务。我不会在生产代码中真正推荐这个。但如果你想走这条路,你可以这样做:

(部分代码取自this answer,修改为CreateFile

await