检测CancelIoEx是否同步取消

时间:2014-08-30 00:06:10

标签: c++ winapi networking asynchronous iocp

我正在为基于IOCP的网络内容添加每个异步操作超时,因此我可以在C ++中使用与Java的NIO.2类似的接口。我已经实现了一个优先级超时队列,支持随机访问删除(这样当操作成功完成时,我可以删除其关联的超时)。

我的问题是如何处理超时的发生。现在我用对应于给定超时的重叠结构调用CancelIoEx。但是,我刚刚在MSDN上阅读了这篇文章:

  

如果文件句柄与完成端口,I / O相关联   如果是同步操作,则完成数据包不会排队到端口   已成功取消。对于仍在等待的异步操作,   取消操作将排队I / O完成包。

我使用使用完成处理程序扩展的重叠结构(每个操作用户提供的std :: function接收错误代码和写入/读取的字节),每当完成数据包出列时执行(同样,非常类似于Java的NIO.2 API)。如果取消异步发生,则完成处理程序将照常运行并获得ERROR_OPERATION_ABORTED。但是,如果CancelIoEx成功立即取消操作怎么办?听起来,通过上面的引用,我需要在那时执行处理程序,因为我以后不会得到完成包。但我如何知道是哪种情况,即完成数据包是否排队或操作是否立即取消?与其他异步操作不同,CancelIoEx不会生成ERROR_IO_PENDING,以区分任务的同步和异步完成(在这种情况下取​​消)。或者,我读错了,任何重叠操作都被认为是异步的(注意:我有设置FILE_SKIP_COMPLETION_PORT_ON_SUCCESS,但是再次只适用于成功,而不是错误,我认为不会影响取消)?

1 个答案:

答案 0 :(得分:3)

它不是在谈论CancelIoEx是同步还是异步,而是说I / O本身(例如ReadFile)是同步还是异步。它描述了同步和异步操作之间的行为差​​异。

  

如果文件句柄与完成端口,I / O相关联   如果是同步,则完成数据包不会排队到端口   操作已成功取消。用于异步操作   仍然挂起,取消操作将排队I / O完成   分组。

同步操作 - 没有OVERLAPPED结构的操作,或者会立即完成的操作 - 将返回错误ERROR_OPERATION_ABORTED

异步操作系统 - 具有OVERLAPPED结构但无法立即完成的操作系统 - 将在ERROR_OPERATION_ABORTED排队完成通知。