如何异步打开Windows中的文件

时间:2016-12-23 11:44:29

标签: .net windows file winapi asynchronous

有没有办法在Windows中异步打开文件? CreateFile API函数只有FILE_FLAG_OVERLAPPED,允许进一步的异步读写。尽管如此,文件的打开似乎是同步的。鉴于,它必须访问文件系统(并可能执行昂贵的IO操作),它可能是一个潜在的阻止程序。

这实际上是一个潜在的问题,是否可以异步打开.NET中的文件(因为无法等待FileStream ctor)。但如果在操作系统中无法做到这一点,那么这个问题就毫无意义了。

3 个答案:

答案 0 :(得分:6)

不幸的是,在用户模式下无法异步创建/打开文件。即使驱动程序为IRP_MJ_CREATE返回STATUS_PENDING,系统也会在这种情况下等待,直到驱动程序完成IRP,然后才能从其中一个创建/打开文件函数返回控制权。 / p>

只有当我们处于内核模式时,如果你自己格式化IRP_MJ_CREATE并将其发送给驱动程序,它才有可能。但即使在这种情况下,驱动程序也几乎总是同步处理IRP_MJ_CREATE

对于API,

是异步的 - 在操作完成时必须以某种方式通知调用者

windows使用了3种方法

  1. 参数中的一些回调例程,通常是APC(PIO_APC_ROUTINE) 操作完成后调用
  2. 参数中的一些事件,当操作完成时,将设置事件 信号状态。
  3. 在lii调用中使用的
  4. 文件句柄被绑定用于某些IOCP。什么时候 操作完成的数据包排队到IOCP。 (我们稍后会通过致电GetQueuedCompletionStatusZwRemoveIoCompletion)或KeRemoveQueue
  5. 删除此数据包

    3)在我们的情况下是不可能的,因为文件句柄还没有创建,所以它不能绑定到任何IOCP。约1)和2)让文件打开/创建api签名:

    在用户模式下,打开/创建文件的最低级别api为ZwOpenFileZwCreateFileCreateFileZwCreateFile以上的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中仍无法做到这一点,这很疯狂。