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.htmlhttp://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()是同步的还是异步的,都会向完成端口发出信号。

    10-06 12:07