Reputation: 2008
Is there a way to open a file in Windows asynchronously? The CreateFile API function has only FILE_FLAG_OVERLAPPED which allows for further asynchronous reads and writes. Nonetheless, the opening of the file seems to be synchronous. Given, it has to access the file system (and potentially perform expensive IO operations), it may be a potential blocker.
This is actually an underlying question to, whether it is possible to open a file in .NET asynchronously (as FileStream ctor cannot be awaited). But the question is rather pointless if there is no way to do it in the OS.
Upvotes: 8
Views: 2726
Reputation: 1207
Unfortunately the CreateFile mechanism conflates the concept of creation of the handle with the concept of associating it with a named file on a disk somewhere.
whereas with sockets, you call a function to create a socket handle, then associate it (bind it) with an endpoint (effectively a name).
MS could have done something similar for files, where you would allocate the handle first unbound, then associate it with a completion port, then asynchronously request association with a file path, which could then be signalled upon completion.
Because face it, underlying all the network redirector stuff is asynchronous, and all the management of IRPs by the IO manager are as well.
It's crazy that after 30 years, there's still no way to do this in Windows.
Upvotes: 0
Reputation: 33754
Unfortunately there is no way in user mode to create/open a file asynchronously. Even if the driver returns STATUS_PENDING
for IRP_MJ_CREATE
, the system will be waiting in this case until the driver completes the IRP
before it returns control from one of the create/open file functions.
Only if we are in kernel mode it's possible, if you yourself format IRP_MJ_CREATE
and send it to the driver. But even in this case the drivers will almost always handle IRP_MJ_CREATE
synchronously.
for API be asynchronous - must be some way notify caller when operation finished
windows used 3 ways for this
PIO_APC_ROUTINE
)
which called when operation finishedGetQueuedCompletionStatus
(ZwRemoveIoCompletion
) or KeRemoveQueue
3) is impossible in our case because file handle yet not created, so it can not be bind to any IOCP. about 1) and 2) let looks for file open/create api signatures:
in user mode the lowest level api for open/create file is ZwOpenFile
and ZwCreateFile
. CreateFile
is shell over ZwCreateFile
. in kernel mode NtOpenFile
-> NtCreateFile
-> IoCreateFile
-> IoCreateFileEx
even - IoCreateFileEx
(the most low level api for create file) - have no Event or [Apc] callback parameter - so not asynchronously. IoCreateFileEx
call ObOpenObjectByName
(not documented, but exported routine) - here also no 1) or 2) parameters - again this is synchronous by design api
Upvotes: 7
Reputation: 457057
Is there a way to open a file in Windows asynchronously?
No, unfortunately. Interestingly, at the device driver level, all such interaction is asynchronous (or can be asynchronous, at least). But that is not exposed at the Win32 level.
The UWP asynchronous file-open APIs are just fake-asynchronous APIs - they delegate synchronous work to the thread pool. They're not truly asynchronous. You'll need to do the same thing if you want non-blocking file-opens on .NET (which is often desirable if you're dealing with files over a network share).
Upvotes: 7