【问题标题】:What if CancelIo fails?如果 CancelIo 失败怎么办?
【发布时间】:2011-04-26 09:43:29
【问题描述】:

调用CancelIo 的原因有很多,但在我的特殊情况下,我调用它是为了知道系统不再写入缓冲区。一旦知道这一点,我就可以安全地释放缓冲区了。

但是如果CancelIo 失败了怎么办?我现在要做的是显式泄漏缓冲区并抛出异常。有没有更好的方法来解决这个问题?

附:对欧罗巴、木卫三和卡利斯托的类似呼唤似乎不见了。我应该提交错误吗?

【问题讨论】:

    标签: winapi asynchronous io cancelio


    【解决方案1】:

    我的回答可能与您的问题无关。但可能会有所帮助..

    在异步 IO..CancelIoEx 中取消挂起的 IO。 如果有待处理的 IO,则返回 1 并生成完成消息或调用完成代码。 如果没有挂起的 IO,它返回 0,错误码为 1168..没有完成消息,也没有调用完成代码。 但实际上。在调用 cancelioex 之后可能会到达预定的 IO。 这都是万恶之源。 我以为取消了所有的IO。但仍有剩余的 IO..

    【讨论】:

      【解决方案2】:

      我认为这里没有比我已经找到的答案更令人满意的答案了:

      泄漏缓冲区(并引发异常(或为您的环境执行等效操作))。

      【讨论】:

        【解决方案3】:

        您不应在发出取消请求后立即删除缓冲区。

        取自CancelIoEx 文档:

        如果指定文件句柄有任何挂起的 I/O 操作正在进行,CancelIoEx 函数会将它们标记为取消。大多数类型的操作可以立即取消;其他操作可以在实际取消并通知调用者之前继续完成。 CancelIoEx 函数不会等待所有已取消的操作完成。

        所以CancelIo 并没有“释放”io 操作,而只是将其标记为“已取消”。您必须等待异步读取/写入的结果才能完成(成功或使用ERROR_OPERATION_ABORTED

        【讨论】:

        • 不用担心。我在释放缓冲区之前等待相关事件。
        • 请注意,此限制适用于CancelIoEx,您仍需调用GetOverlappedResultCancelIO,似乎是同步取消(可能是因为它无论如何都在发出线程上调用)
        【解决方案4】:

        MSDN 文档对可能返回的错误不是很清楚。我想(因为CancelIo 无论如何都是异步的)这意味着您使用了错误的句柄,或者类似的东西。我所说的异步是指仅仅因为 CancelIo 返回 OK,您不能立即为任何挂起的 I/O 释放缓冲区。

        在文档中声明待处理的 I/O 将返回 ERROR_OPERATION_ABORTED。我认为您已经跟踪了挂起的 I/O 状态,这样当且仅当所有挂起的 I/O 都返回此错误时,您才能安全地释放缓冲区。如果在CancelIo 之后挂起的 I/O 处于挂起状态,则释放缓冲区可能会导致一系列不良副作用。

        【讨论】:

        • 没错。这就是我(目前)泄漏缓冲区的原因。
        • 如果您无法考虑待处理的 IO,我认为别无选择。
        猜你喜欢
        • 1970-01-01
        • 2019-02-10
        • 2011-06-14
        • 2012-08-01
        • 1970-01-01
        • 2010-12-31
        • 2016-01-11
        • 2021-12-22
        • 1970-01-01
        相关资源
        最近更新 更多