You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

收到operation_canceled的完成处理器中发起新异步操作是否合法?

问题解答

核心结论

当完成处理器接收到boost::asio::error::operation_canceled错误时,在同一个I/O对象上发起新的异步操作是语义有效的,无需将该I/O对象视为“无效”。

原因说明

operation_canceled错误仅表示当前触发的异步操作被主动取消(比如调用了socket.cancel()),但I/O对象自身的状态并未被破坏。只要对象处于合法状态(如套接字未关闭、未被销毁),就可以继续发起新的异步操作。

代码验证与说明

你提供的代码中,在第一个async_receive被取消后,在完成处理器内发起第二个async_receive的逻辑完全合法。以下是补充中文注释后的代码:

#include <boost/asio.hpp>
#include <iostream>

int main()
{
    try {
        boost::asio::io_context io_context;

        // 创建UDP套接字并绑定到本地端点
        boost::asio::ip::udp::socket socket(io_context);
        boost::asio::ip::udp::endpoint local_endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 54321);
        socket.open(boost::asio::ip::udp::v4());

        socket.bind(local_endpoint);

        std::vector<std::uint8_t> buffer(100);
        socket.async_receive(boost::asio::buffer(buffer.data(), buffer.size()), [&socket, &buffer](boost::system::error_code ec, std::size_t len)
                             {
                                 if (!ec) {
                                     std::cout << "1: UDP-Server: 接收字节数: " << len << std::endl;
                                 } else if (ec == std::errc::operation_canceled) {
                                     // 此处语义有效,可正常发起新的异步接收操作
                                     socket.async_receive(boost::asio::buffer(buffer.data(), buffer.size()),
                                                          [&socket, &buffer](boost::system::error_code ec, std::size_t len) {
                                                              if (!ec) {
                                                                  std::cout << "2: UDP-Server: 接收字节数: " << len << std::endl;
                                                              }
                                                          });
                                 }
                             });

        socket.cancel(); // 主动取消第一个异步接收操作
        io_context.run();

    } catch (std::exception &e) {
        std::cerr << "意外异常: " << e.what() << std::endl;
    }

    return 0;
}

关键注意事项

  • 只有当I/O对象被关闭(如调用socket.close())或销毁后,才无法发起新的异步操作,此时会触发boost::asio::error::bad_descriptor类错误。
  • 需确保lambda捕获的变量(如socket、buffer)在新异步操作的生命周期内保持有效,避免悬空引用导致未定义行为。

内容的提问来源于stack exchange,提问作者Degoah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:20:06