首页 > 解决方案 > Boost asio 截止时间计时器立即完成(C++)

问题描述

下面的代码会立即打印“已连接”到控制台,而不是 10 秒后。为什么是这样?这与我传递print回调的方式有关吗?

void print(const boost::system::error_code& e) {
  std::cout << "connected!" << std::endl;
}

class WebSocketSession {
 public:
  WebSocketSession(asio::io_context &io_context) : io_context_(io_context) {}
  void connect() {
    boost::asio::deadline_timer
        timer(io_context_, boost::posix_time::seconds(10));
    timer.async_wait(&print);
  }
 private:
  asio::io_context &io_context_;
};

class WebSocketClient {
 public:
  WebSocketClient(asio::io_context &io_context) : io_context_(io_context) {}
  std::unique_ptr<WebSocketSession> exec() {
    auto session = std::make_unique<WebSocketSession>(io_context_);
    session->connect();
    return session;
  }
 private:
  asio::io_context &io_context_;
};

int main() {
  asio::io_context io_context;
  WebSocketClient client{io_context};
  std::unique_ptr<WebSocketSession> session = client.exec();
  io_context.run();
  return 0;
}

标签: c++boostboost-asio

解决方案


正如评论中提到的,deadline_timer因为它是一个局部变量而过早地被销毁,从而取消了 I/O 操作。

如果我们添加一些错误处理,我们将看到报告的实际错误:

void print(const boost::system::error_code& e) {
    if (e.failed())
        std::cout << "error: " << e.message() << std::endl;
    else
        std::cout << "connected!" << std::endl;
}

印刷:

error: The I/O operation has been aborted because of either a thread exit or an application request

一个可能的解决方法是deadline_timer成为以下成员WebSocketSession

class WebSocketSession {
public:
    WebSocketSession(boost::asio::io_context& io_context) : io_context_(io_context),
        timer_(io_context, boost::posix_time::seconds(10)) {}
    void connect() {
        timer_.async_wait(&print);
    }
private:
    boost::asio::io_context& io_context_;
    boost::asio::deadline_timer timer_;
};

推荐阅读