【发布时间】:2019-12-06 19:03:49
【问题描述】:
我正在使用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
【问题讨论】:
-
你猛拉地垫,它必须完成。在那之前您不能安全地删除 OVERLAPPED,可能的内存损坏很难诊断。
-
对不起,我不明白你的意思,什么布尔变量?完成例程是一个静态函数,
LPOVERLAPPED不再有用,(那时它是未定义的)。 -
只有在 I/O 完成后才能删除 lpOverlapped 指向的内存 - 这意味着如果
ReadDirectoryChangesW返回 false 或内部回调 -
是的,我明白了,但问题是在我关闭句柄之后(在读取和回调之间),我不再需要任何消息。例如,如果我从未收到回电怎么办?我不能永远保持 lpOverlapped 希望它会被调用。
-
@FFMG 如果 i/o 启动正常 (
ReadDirectoryChangesW) 返回 true - 你保证它会完成。它在文件上调用CloseHandle或CancelIo后完成。当 i/o 完成时 - apc 将排队到您的线程(因为您使用 apc 完成)。但只有当您执行警报等待或调用NtTestAlert时才会调用用户模式 apc。问题是您不了解这里的内部对象管理。免费/删除的内容和时间。
标签: winapi readdirectorychangesw