tags:

views:

702

answers:

3

I want to monitor the modifications in a specified directory, and retrieve the exact change information. So I've decided to use the ReadDirectoryChangesW() function. But I want to use it asynchronously, which means I don't want my worker thread to be blocked if there's no changes in the directory. How can I do this?

Thank you!

+1  A: 

From the MSDN documentation for ReadDirectoryChnagesW():

For asynchronous completion, you can receive notification in one of three ways:

  • Using the GetOverlappedResult function. To receive notification through GetOverlappedResult, do not specify a completion routine in the lpCompletionRoutine parameter. Be sure to set the hEvent member of the OVERLAPPED structure to a unique event.
  • Using the GetQueuedCompletionStatus function. To receive notification through GetQueuedCompletionStatus, do not specify a completion routine in lpCompletionRoutine. Associate the directory handle hDirectory with a completion port by calling the CreateIoCompletionPort function.
  • Using a completion routine. To receive notification through a completion routine, do not associate the directory with a completion port. Specify a completion routine in lpCompletionRoutine. This routine is called whenever the operation has been completed or canceled while the thread is in an alertable wait state. The hEvent member of the OVERLAPPED structure is not used by the system, so you can use it yourself.
csgero
Thank you! But I'm a little confused by what MSDN says. Can you explain a little more?
I want to know which method is better if I want to monitor more than one directory simultaneously in a single thread.
+2  A: 

I tend to use ReadDirectoryChangesW() with an I/O Completion port, which is good for when you want to monitor multiple directories because you can have a single thread servicing the IOCP and dealing with the results from all of your calls to ReadDirectoryChangesW().

First create an IOCP, once, by calling CreateIoCompletionPort(). Start a thread that calls GetQueuedCompletionStatus() and deals with your async directory changes.

Now for each directory that you want to monitor. First open your directory handle as normal. Next associate it with your IOCP by calling CreateIoCompletionPort() and passing the IOCP handle in (see docs for more details). Finally call ReadDirectoryChangesW() and pass an OVERLAPPED as detailed in the docs. The call will return and if successful the results will become available as the results of GetQueuedCompletionStatus() in the thread that you created to service the IOCP.

Len Holgate
Thank you! I want to use completion routine. Do you have any idea about that?
Another question is, how can I retrieve the change information from GetQueuedCompletionStatus() method? Is it included in the OVERLAPPED structure?
I've not used completion routines as they're more complex to use as you need to ensure that the thread that calls ReadDirectoryChangesW() is in an alertable wait state...
Len Holgate
What I do is create a class that inherits from OVERLAPPED and contains a buffer for the data. I then create one of these per watch and pass it to ReadDirectoryChangesW(). When GetQueuedCompletionStatus() returns you have a pointer to the class and can access the data just as if you made a sync call.
Len Holgate
A: 

Have a look at this:

FolderControl implementation

This is a german forum but the important stuff is english. It has a nice little component that wraps all this stuff and is coded in a very clean way.

Smasher