关闭句柄后调用的 ReadDirectoryChangesW 异步完成例程
ReadDirectoryChangesW Asynchronous Completion routine called after I close the handle
我正在使用 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
您正在关闭您的 HANDLE
并释放您的 OVERLAPPED
太早了。
CancelIo()
(以及它的跨线程兄弟,CancelIoEx()
)简单地将活动的I/O操作标记为已取消然后退出,但您仍然需要实际等待这些操作完成完全完成,然后才能释放他们的 OVERLAPPED
.
如果操作在完成其工作之前注意到取消,它将停止其工作并报告完成并返回错误代码 ERROR_OPERATION_ABORTED
,否则它将正常完成其工作并使用适当的错误代码报告完成错误代码。
调用CancelIo/Ex()
后,您需要继续等待和处理已完成的操作,直到没有更多操作可等待。
也就是说,调用CancelIo()
后确实可以调用MyCompletionRoutine()
,再次调用Read()
之前需要检查ERROR_OPERATION_ABORTED
。如果在调用 CancelIo()
时有正在进行的读取,则需要等待该读取完成。
我正在使用 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
您正在关闭您的 HANDLE
并释放您的 OVERLAPPED
太早了。
CancelIo()
(以及它的跨线程兄弟,CancelIoEx()
)简单地将活动的I/O操作标记为已取消然后退出,但您仍然需要实际等待这些操作完成完全完成,然后才能释放他们的 OVERLAPPED
.
如果操作在完成其工作之前注意到取消,它将停止其工作并报告完成并返回错误代码 ERROR_OPERATION_ABORTED
,否则它将正常完成其工作并使用适当的错误代码报告完成错误代码。
调用CancelIo/Ex()
后,您需要继续等待和处理已完成的操作,直到没有更多操作可等待。
也就是说,调用CancelIo()
后确实可以调用MyCompletionRoutine()
,再次调用Read()
之前需要检查ERROR_OPERATION_ABORTED
。如果在调用 CancelIo()
时有正在进行的读取,则需要等待该读取完成。