在我的工作线程中,我需要能够在用户输入时停止长文件操作。我目前的方法是在一个小缓冲区上重复调用ReadFile
,然后在每次迭代后调用回调函数。像这样:
//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;
}
此方法有效。但是,当我进行基准测试时,看看它对一个简单的调用运行速度有多慢:
::ReadFile(hFile, FullBuffer, nSizeOfFullBuffer, nBytesRead);
SSD(随机存取磁盘)的差别并不大,但当我从旋转驱动器读取大文件时,它变得非常明显。例如,使用单个ReadFile
读取4GB文件大约需要32秒,使用上面的回调使用我的方法大约需要46秒。 (我知道由于在旋转磁盘上重复调用ReadFile
,会发生更大的延迟。)
所以我想知道是否有更有效的方法来做到这一点?
答案 0 :(得分:4)
可能最明显的可能性是使用ReadFileEx
进行重叠读取。然后,您可以在必要时使用CancelIo
取消I / O.
由于这是重叠的,您可以直接从父线程调用它,而不是创建专用于I / O的线程。主要要求是当调用线程准备处理来自重叠I / O的反馈时,调用线程进入可警告的等待状态。在父线程使用GetMessage
循环的典型情况下,您需要将其更改为使用MsgWaitForMultipleObjectsEx
。这使您可以继续检索消息,但也进入可警告的等待状态,因此也可以调用传递给ReadFileEx
的回调。