0

ReadDirectoryChangesW用来监视目录中文件何时更改。我正在使用带有完成例程函数的异步版本(根据文档)。

一切正常,直到我希望停止监视该文件夹。

为了停止监控,我调用了这个Close函数。

问题是我仍然收到最后一个通知,但到那时我已经破坏了我的LPOVERLAPPED价值。

如何停止ReadDirectoryChangesW并阻止MyCompletionRoutine调用我的函数。

// get the handle    
_handle = CreateFileW( ... )

void Read()
{
  ...
  ReadDirectoryChangesW( _handle, ..., &MyCompletionRoutine );
  ...
}

void Close()
{
  ::CancelIo(_handle );           
  ::CloseHandle(_handle );
}

void __stdcall MyCompletionRoutine (
    const unsigned long dwErrorCode,
    const unsigned long dwNumberOfBytesTransfered,
    _OVERLAPPED* lpOverlapped )
{
  // ... do stuff and start a read again
  Read();
}

在上面的代码中,我可能已经调用Read但我想在MyCompletionRoutine调用之前停止。

不知道这是否有帮助,但我得到的错误信息是317

4

1 回答 1

3

你正在关闭你的HANDLE并释放你的OVERLAPPED太快了。

CancelIo()(以及它的跨线程兄弟CancelIoEx())只需将活动 I/O 操作标记为已取消然后退出,但您仍然需要真正等待这些操作完全完成,然后才能释放它们的OVERLAPPED.

如果一个操作在完成它的工作之前注意到取消,它将停止它的工作并报告一个错误代码的完成ERROR_OPERATION_ABORTED,否则它将正常完成它的工作并用适当的错误代码报告一个完成。

调用后CancelIo/Ex(),您需要继续等待并处理已完成的操作,直到没有更多操作可以等待。

也就是说,MyCompletionRoutine()确实可以在被调用之后CancelIo()调用,并且需要在再次ERROR_OPERATION_ABORTED调用之前进行检查Read()。如果在被调用时有一个正在等待的读取CancelIo(),您需要等待该读取完成。

于 2019-12-06T19:51:17.180 回答