有没有办法在 Windows 中异步打开文件? CreateFile API 函数只有 FILE_FLAG_OVERLAPPED 允许进一步的异步读写。尽管如此,文件的打开似乎是同步的。鉴于它必须访问文件系统(并可能执行昂贵的 IO 操作),它可能是一个潜在的障碍。
这实际上是一个潜在的问题,是否可以在 .NET 中异步打开文件(因为无法等待 FileStream ctor)。但如果在操作系统中没有办法做到这一点,那么这个问题就毫无意义了。
最佳答案
不幸的是,在用户模式下无法异步创建/打开文件。即使驱动程序为 IRP_MJ_CREATE
返回 STATUS_PENDING
,在这种情况下,系统将等待,直到驱动程序完成 IRP
,然后它才能从创建/打开文件函数之一返回控制权。
只有当我们处于内核模式时才有可能,如果你自己格式化 IRP_MJ_CREATE
并将其发送给司机。但即使在这种情况下,驱动程序也几乎总是会处理 IRP_MJ_CREATE
同步。
API 是异步的 - 必须以某种方式在操作完成时通知调用者
Windows 为此使用了 3 种方式
- 参数中的一些回调例程,通常是 APC (
PIO_APC_ROUTINE
) 操作完成时调用 - 参数中的一些Event,当操作完成时,Event set in 信号状态。
- 在 api 调用中使用的文件句柄是为某些 IOCP 绑定(bind)的。什么时候
操作完成的数据包排队到 IOCP。 (我们稍后通过调用
GetQueuedCompletionStatus
(ZwRemoveIoCompletion
) 或KeRemoveQueue
删除此数据包
3) 在我们的例子中是不可能的,因为文件句柄还没有创建,所以它不能绑定(bind)到任何 IOCP。关于 1) 和 2) 查找文件打开/创建 api 签名:
在用户模式下,打开/创建文件的最低级别 API 是 ZwOpenFile
和 ZwCreateFile
. CreateFile
是 ZwCreateFile
的外壳。在内核模式 NtOpenFile
-> NtCreateFile
-> IoCreateFile
-> IoCreateFileEx
甚至 - IoCreateFileEx
(用于创建文件的最低级 API)- 没有事件或 [Apc] 回调参数 - 所以不是异步的。 IoCreateFileEx
调用 ObOpenObjectByName
(未记录,但导出例程) - 这里也没有 1) 或 2) 参数 - 同样这是设计 api 同步
关于.net - 如何在Windows中异步打开一个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41300873/