.net - 如何在Windows中异步打开一个文件

标签 .net windows file winapi asynchronous

有没有办法在 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 种方式

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

3) 在我们的例子中是不可能的,因为文件句柄还没有创建,所以它不能绑定(bind)到任何 IOCP。关于 1) 和 2) 查找文件打开/创建 api 签名:

在用户模式下,打开/创建文件的最低级别 API 是 ZwOpenFileZwCreateFile . CreateFileZwCreateFile 的外壳。在内核模式 NtOpenFile -> NtCreateFile -> IoCreateFile -> IoCreateFileEx甚至 - IoCreateFileEx (用于创建文件的最低级 API)- 没有事件或 [Apc] 回调参数 - 所以不是异步的。 IoCreateFileEx调用 ObOpenObjectByName(未记录,但导出例程) - 这里也没有 1) 或 2) 参数 - 同样这是设计 api 同步

关于.net - 如何在Windows中异步打开一个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41300873/

相关文章:

.net - 使用客户端凭据通过 SSL 的 HttpWebRequest

c# - 查找datagridview复选框值时如何停止空引用异常?

c# - 在 C# 中通过 "dynamic overload"进行单/双分派(dispatch)

python - PyWin32获取网络信息/统计数据

linux - 如何批量调整数百万张图片的大小以适应最大宽度和高度?

c# - .NET 解决方案 - 许多项目与一个项目

c - 从键盘获取输入,无需等待输入

windows -\Windows\versus\Windows\System32 - 文件位置约定

Java将xml文件内容存储到字符串中

java - Sonar-使用 try-with-resources 或在 "Stream"子句 java8 流中关闭此 "finally"