如何异步打开Windows中的文件

Ele*_*tik 4 .net windows winapi asynchronous file

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

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

RbM*_*bMm 6

不幸的是,在用户模式下无法异步创建/打开文件.即使驱动程序返回STATUS_PENDINGIRP_MJ_CREATE,系统会在这种情况下,直到驱动程序完成等待IRP它的创建/打开文件的功能之一返回控制之前.

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


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

windows使用了3种方法

  1. 参数中的一些回调例程,通常是APC(PIO_APC_ROUTINE),当操作完成时调用
  2. 参数中的一些事件,当操作完成时,事件设置为信号状态.
  3. 在api调用中使用的文件句柄被绑定用于某些IOCP.当操作完成时,数据包排队到IOCP.(我们稍后通过call GetQueuedCompletionStatus(ZwRemoveIoCompletion)或删除此数据包KeRemoveQueue

3)在我们的情况下是不可能的,因为文件句柄还没有创建,所以它不能绑定到任何IOCP.关于1)和2)让我们查找文件open/create api签名:

在用户模式下,打开/创建文件的最低级别api是ZwOpenFileZwCreateFile.CreateFile贝壳结束了ZwCreateFile.在内核模式NtOpenFile- > NtCreateFile- > IoCreateFile- > IoCreateFileEx偶 - IoCreateFileEx(创建文件的最低级api) - 没有Event或[Apc]回调参数 - 所以不是异步的.IoCreateFileEx调用ObOpenObjectByName(没有记录,但导出的例程) - 这里也没有1)或2)参数 - 再次这是设计api同步


Ste*_*ary 5

有没有一种方法可以在Windows中异步打开文件?

不,很不幸。有趣的是,在设备驱动程序级别,所有此类交互都是异步的(或至少可以是异步的)。但这在Win32级别上并未公开。

UWP异步文件打开API只是伪异步API,它们将同步工作委托给线程池。它们不是真正的异步。如果要在.NET上进行非阻塞文件打开,则需要执行相同的操作(如果要通过网络共享处理文件,这通常是合乎需要的)。

  • “在设备驱动程序级别,所有此类交互都是异步的(或者至少可以是异步的)。” - 仅当直接发送 IRP_MJ_CREATE - *可以*是异步的。甚至 `IoCreateFile` 或 `ObOpenObjectByName` - 同步 api (2认同)