CancelIo()应该取消与调用线程关联的所有待处理的 I/O操作。以我的经验,CancelIo()有时也会取消将来的 I/O操作。鉴于:
ReadFile(port, buffer, length, &bytesTransferred, overlapped);
CancelIo(port)
,则GetQueuedCompletionStatus()
将永远阻塞,永远不会接收读取操作。 CancelIo(port)
,则GetQueuedCompletionStatus()
将返回0,其中包含GetLastError()==ERROR_OPERATION_ABORTED
CancelIo(port)
且没有未决的或后续的读取,则GetQueuedCompletionStatus()
将永远阻塞。 这里的关键点是无法检测到
CancelIo()
完成执行的时间。如何确保CancelIo()
完成执行并且可以安全地发出进一步的读取请求?PS:查看http://osdir.com/ml/lib.boost.asio.user/2008-02/msg00074.html和http://www.boost.org/doc/libs/1_44_0/doc/html/boost_asio/using.html,听起来好像CancelIo()确实不可用。客户必须要求Windows XP支持。我有什么选择?
注意:我正在从串行端口读取。
最佳答案
CancelIo()
正常工作。我误解了我的代码。
经过进一步调查,结果发现该代码正在调用CancelIo()
,然后调用ReadFile()
并带有超时INFINITE
。完成端口永远不会收到读取通知,因为远程端从不发送任何内容。换句话说,CancelIo()
不会取消后续操作。
我发现了一些令人惊讶的文档here:
事实证明,如果正在读取的数据已被设备驱动程序缓存,则设备驱动程序可以选择以同步方式处理异步操作。经过进一步调查,我发现在CancelIo()
之前调用ReadFile()
时,有时会导致后者同步返回。我不知道为什么在ReadFile()
之后从未从CancelIo()
通知完成端口,但是我再也无法重现此问题。
无论ReadFile()
是同步的还是异步的,都会向完成端口发出信号。