Elephantik
Elephantik

Reputation: 2008

How to open a file in windows asynchronously

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

Answers (3)

Adrien
Adrien

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

RbMm
RbMm

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

  1. some callback routine in parameters, usually APC (PIO_APC_ROUTINE) which called when operation finished
  2. some Event in parameters, when operation finished, Event set in signal state.
  3. file handle, used in api call, is binded for some IOCP. when operation finished packet is queued to IOCP. (we remove this packet later by call GetQueuedCompletionStatus (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

Stephen Cleary
Stephen Cleary

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

Related Questions