有没有办法在Windows中异步打开文件? CreateFile API函数只有FILE_FLAG_OVERLAPPED,允许进一步的异步读写。尽管如此,文件的打开似乎是同步的。鉴于,它必须访问文件系统(并可能执行昂贵的IO操作),它可能是一个潜在的阻止程序。
这实际上是一个潜在的问题,是否可以异步打开.NET中的文件(因为无法等待FileStream ctor)。但如果在操作系统中无法做到这一点,那么这个问题就毫无意义了。
答案 0 :(得分:6)
不幸的是,在用户模式下无法异步创建/打开文件。即使驱动程序为IRP_MJ_CREATE
返回STATUS_PENDING
,系统也会在这种情况下等待,直到驱动程序完成IRP
,然后才能从其中一个创建/打开文件函数返回控制权。 / p>
只有当我们处于内核模式时,如果你自己格式化IRP_MJ_CREATE
并将其发送给驱动程序,它才有可能。但即使在这种情况下,驱动程序也几乎总是同步处理IRP_MJ_CREATE
。
是异步的 - 在操作完成时必须以某种方式通知调用者
windows使用了3种方法
PIO_APC_ROUTINE
)
操作完成后调用GetQueuedCompletionStatus
(ZwRemoveIoCompletion
)或KeRemoveQueue
3)在我们的情况下是不可能的,因为文件句柄还没有创建,所以它不能绑定到任何IOCP。约1)和2)让文件打开/创建api签名:
在用户模式下,打开/创建文件的最低级别api为ZwOpenFile
和ZwCreateFile
。 CreateFile
是ZwCreateFile
以上的shell。在内核模式NtOpenFile
- > NtCreateFile
- > IoCreateFile
- > IoCreateFileEx
偶 - IoCreateFileEx
(创建文件的最低级api) - 没有Event或[Apc]回调参数 - 所以不是异步的。 IoCreateFileEx
调用ObOpenObjectByName
(未记录,但导出例行程序) - 此处也没有1)或2)参数 - 再次这是设计api同步
答案 1 :(得分:4)
有没有办法在Windows中异步打开文件?
不,不幸的是。有趣的是,在设备驱动程序级别,所有此类交互都是异步的(或至少可以异步)。但是在Win32级别没有公开。
UWP异步文件打开API只是伪异步API - 它们将同步工作委托给线程池。它们并非真正异步。如果你想在.NET上打开非阻塞文件,你需要做同样的事情(如果你通过网络共享处理文件,这通常是可取的。)
答案 2 :(得分:0)
不幸的是,CreateFile机制将句柄创建的概念与将其与某个磁盘上的命名文件相关联的概念混淆。
而对于套接字,您调用函数来创建套接字句柄,然后将其与端点(实际上是名称)关联(绑定)。
MS可能已经为文件做了类似的事情,您将首先分配未绑定的句柄,然后将其与完成端口关联,然后异步请求与文件路径的关联,然后在完成时发出信号。
因为面对它,所有网络重定向器的底层都是异步的,并且IO管理器对IRP的所有管理也是如此。
30年后,在Windows中仍无法做到这一点,这很疯狂。