Dot-Net

如何在windows中非同步打開文件

  • April 28, 2017

有沒有辦法在 Windows 中非同步打開文件?CreateFile API 函式只有 FILE_FLAG_OVERLAPPED 允許進一步的非同步讀寫。儘管如此,文件的打開似乎是同步的。鑑於它必須訪問文件系統(並可能執行昂貴的 IO 操作),它可能是一個潛在的阻塞器。

這實際上是一個潛在的問題,是否可以在 .NET 中非同步打開文件(因為不能等待 FileStream ctor)。但是,如果在作業系統中沒有辦法做到這一點,那麼這個問題就毫無意義了。

不幸的是,在使用者模式下無法非同步創建/打開文件。即使驅動程序返回STATUS_PENDINGfor IRP_MJ_CREATE,在這種情況下,系統將等待驅動程序完成,IRP然後再從創建/打開文件函式之一返回控制權。

只有當我們處於核心模式時才有可能,如果您自己格式化IRP_MJ_CREATE並將其發送給驅動程序。但即使在這種情況下,驅動程序幾乎總是會IRP_MJ_CREATE同步處理。


對於 API 是非同步的 - 必須以某種方式在操作完成時通知呼叫者

windows為此使用了3種方法

  1. 參數中的一些回調常式,通常是PIO_APC_ROUTINE操作完成時呼叫的 APC ( )
  2. 參數中的一些事件,當操作完成時,事件設置為信號狀態。
  3. 在 api 呼叫中使用的文件句柄是為某些 IOCP 綁定的。當操作完成數據包排隊到 IOCP。(我們稍後通過呼叫GetQueuedCompletionStatusZwRemoveIoCompletion)刪除此數據包或KeRemoveQueue
  1. 在我們的例子中是不可能的,因為文件句柄還沒有創建,所以它不能綁定到任何 IOCP。關於 1) 和 2) 讓我們查找文件打開/創建 api 簽名:

在使用者模式下,用於打開/創建文件的最低級別 api 是ZwOpenFileZwCreateFile. CreateFile是殼結束ZwCreateFile。在核心模式NtOpenFile-> NtCreateFile-> IoCreateFile->IoCreateFileEx甚至 - IoCreateFileEx(創建文件的最低級別 api) - 沒有事件或

$$ Apc $$回調參數 - 所以不是非同步的。IoCreateFileEx呼叫ObOpenObjectByName(未記錄,但導出的常式) - 這裡也沒有 1)或 2)參數 - 這也是設計 api 同步的

引用自:https://stackoverflow.com/questions/41300873