第二个定时器
pp
是一个局部变量。它会立即被销毁。
因此,异步操作使用一个已删除的实例并调用
Undefined Behaviour
.
您可能应该通过实际接收来检测取消
error_code
在完成处理程序中。这个
std::bind
表情默默地为你放下,现在。
你可以使用某种动态分配。我还强烈建议将间隔计时器的概念和执行的操作分开并推广:
struct Timer {
using Callback = std::function<bool()>;
Timer(asio::any_io_executor ex, duration d, Callback cb)
: timer_(ex, d)
, interval_(d)
, cb_(std::move(cb)) { do_loop(); }
private:
asio::steady_timer timer_;
duration interval_;
Callback cb_;
void do_loop() {
timer_.async_wait(bind(&Timer::on_tick, this, std::placeholders::_1));
}
void on_tick(error_code ec) {
if (ec) {
std::cerr << "Warning: " << ec.message() << std::endl;
return;
} else if (cb_()) {
timer_.expires_at(timer_.expiry() + interval_);
do_loop();
}
}
};
现在您可以像这样使用它:
#include <boost/asio.hpp>
#include <functional>
#include <iostream>
namespace asio = boost::asio;
using namespace std::chrono_literals;
using boost::system::error_code;
using duration = std::chrono::steady_clock::duration;
struct Timer {
using Callback = std::function<bool()>;
Timer(asio::any_io_executor ex, duration d, Callback cb)
: timer_(ex, d)
, interval_(d)
, cb_(std::move(cb)) { do_loop(); }
private:
asio::steady_timer timer_;
duration interval_;
Callback cb_;
void do_loop() {
timer_.async_wait(bind(&Timer::on_tick, this, std::placeholders::_1));
}
void on_tick(error_code ec) {
if (ec) {
std::cerr << "Warning: " << ec.message() << std::endl;
return;
} else if (cb_()) {
timer_.expires_at(timer_.expiry() + interval_);
do_loop();
}
}
};
int main() {
asio::io_context io;
auto ex = io.get_executor();
auto printer = [](std::string_view name) {
return [name, count_ = 0]() mutable {
bool more = count_ < 5;
std::cout << "Printer " << quoted(name) << (more ? " " : " Last num ") << count_ << "\n";
++count_;
return more;
};
};
std::optional<Timer> second;
Timer first(ex, 1s, printer("First"));
Timer delay(ex, 1500ms, [&] {
second.emplace(ex, 1s, printer("Second"));
return false;
});
io.run();
}
看看吧
Live On Coliru
打印内容:
Printer "First" 0
Printer "First" 1
Printer "Second" 0
Printer "First" 2
Printer "Second" 1
Printer "First" 3
Printer "Second" 2
Printer "First" 4
Printer "Second" 3
Printer "First" Last num 5
Printer "Second" 4
Printer "Second" Last num 5
或者更具互动性: