c00000fd
c00000fd

Reputation: 22327

Method to provide an efficient callback to ReadFile

In my worker thread I need to have an ability to stop a long file operation upon user input. My current approach is to call ReadFile repeatedly on a small buffer and then invoke the callback function after each iteration. Something like this:

//Error checks are omitted for brevity

for(;;)
{
    ::ReadFile(hFile, SmallBuffer, nSizeOfSmallBuffer, nBytesRead);

    if(!pfnCallbackProc())
    {
        //Abort
        break;
    }
}

BOOL callbackProc()
{
    return ::WaitForSingleObject(hStopEvent, 0) == WAIT_OBJECT_0;
}

This method works. But when I did my benchmark tests to see how much slower it runs against a simple call to:

::ReadFile(hFile, FullBuffer, nSizeOfFullBuffer, nBytesRead);

the difference is not that much on an SSD (random access disk), but it becomes quite pronounced when I'm reading a large file from a spinning drive. For instance, reading a 4GB file takes about 32 seconds with a single ReadFile, and about 46 seconds using my method with a callback above. (I understand that a larger delay happens because of repeated calls to ReadFile on a spinning disk.)

So I was wondering if there's a more efficient way to do this?

Upvotes: 1

Views: 755

Answers (1)

Jerry Coffin
Jerry Coffin

Reputation: 490663

Probably the most obvious possibility would be to use ReadFileEx to do an overlapped read. Then you can use CancelIo to cancel the I/O when/if necessary.

Since this is overlapped, you may be able to call it directly from the parent thread instead of creating a thread dedicated to the I/O. The main requirement is that the calling thread go into an alertable wait state when it's ready to process feedback from the overlapped I/O. In a typical case where the parent thread uses a GetMessage loop, you'd change it to use MsgWaitForMultipleObjectsEx instead. That lets you continue to retrieve messages, but also enters the alertable wait state, so the callback you pass to ReadFileEx can be invoked as well.

Upvotes: 4

Related Questions