【发布时间】:2011-04-26 09:43:29
【问题描述】:
调用CancelIo 的原因有很多,但在我的特殊情况下,我调用它是为了知道系统不再写入缓冲区。一旦知道这一点,我就可以安全地释放缓冲区了。
但是如果CancelIo 失败了怎么办?我现在要做的是显式泄漏缓冲区并抛出异常。有没有更好的方法来解决这个问题?
附:对欧罗巴、木卫三和卡利斯托的类似呼唤似乎不见了。我应该提交错误吗?
【问题讨论】:
标签: winapi asynchronous io cancelio
调用CancelIo 的原因有很多,但在我的特殊情况下,我调用它是为了知道系统不再写入缓冲区。一旦知道这一点,我就可以安全地释放缓冲区了。
但是如果CancelIo 失败了怎么办?我现在要做的是显式泄漏缓冲区并抛出异常。有没有更好的方法来解决这个问题?
附:对欧罗巴、木卫三和卡利斯托的类似呼唤似乎不见了。我应该提交错误吗?
【问题讨论】:
标签: winapi asynchronous io cancelio
我的回答可能与您的问题无关。但可能会有所帮助..
在异步 IO..CancelIoEx 中取消挂起的 IO。 如果有待处理的 IO,则返回 1 并生成完成消息或调用完成代码。 如果没有挂起的 IO,它返回 0,错误码为 1168..没有完成消息,也没有调用完成代码。 但实际上。在调用 cancelioex 之后可能会到达预定的 IO。 这都是万恶之源。 我以为取消了所有的IO。但仍有剩余的 IO..
【讨论】:
我认为这里没有比我已经找到的答案更令人满意的答案了:
泄漏缓冲区(并引发异常(或为您的环境执行等效操作))。
【讨论】:
您不应在发出取消请求后立即删除缓冲区。
取自CancelIoEx 文档:
如果指定文件句柄有任何挂起的 I/O 操作正在进行,CancelIoEx 函数会将它们标记为取消。大多数类型的操作可以立即取消;其他操作可以在实际取消并通知调用者之前继续完成。 CancelIoEx 函数不会等待所有已取消的操作完成。
所以CancelIo 并没有“释放”io 操作,而只是将其标记为“已取消”。您必须等待异步读取/写入的结果才能完成(成功或使用ERROR_OPERATION_ABORTED。
【讨论】:
CancelIoEx,您仍需调用GetOverlappedResult。 CancelIO,似乎是同步取消(可能是因为它无论如何都在发出线程上调用)
MSDN 文档对可能返回的错误不是很清楚。我想(因为CancelIo 无论如何都是异步的)这意味着您使用了错误的句柄,或者类似的东西。我所说的异步是指仅仅因为 CancelIo 返回 OK,您不能立即为任何挂起的 I/O 释放缓冲区。
在文档中声明待处理的 I/O 将返回 ERROR_OPERATION_ABORTED。我认为您已经跟踪了挂起的 I/O 状态,这样当且仅当所有挂起的 I/O 都返回此错误时,您才能安全地释放缓冲区。如果在CancelIo 之后挂起的 I/O 处于挂起状态,则释放缓冲区可能会导致一系列不良副作用。
【讨论】: