c++ - 如何调用处理程序?
问题描述
我不明白如何在io_context
停止的情况下返回句柄。最小示例:
void my_class::async_get_one_scan(
std::function<void(const boost::system::error_code& ec,
std::shared_ptr<my_chunked_packet>)> handler)
{
asio::spawn(strand_, [this, handler] (asio::yield_context yield)
{
const auto work = boost::asio::make_work_guard(io_service_);
my_chunk_buffer chunks;
while (!chunks.full()) {
std::array<uint8_t, 1000> datagram;
boost::system::error_code ec;
auto size = socket_.async_receive(asio::buffer(datagram), yield[ec]);
if (!ec)
process_datagram(datagram, size, chunks);
else {
handler(ec, nullptr);
return;
}
}
io_service_.post(std::bind(handler, boost::system::error_code, chunks.packet()));
});
}
调试 asio 输出:
@asio|1532525798.533266|6*7|strand@01198ff0.dispatch
@asio|1532525798.533266|>7|
@asio|1532525798.533266|>0|
@asio|1532525798.533266|0*8|socket@008e345c.async_receive
@asio|1532525798.533266|<7|
@asio|1532525798.533266|<6|
@asio|1532525799.550640|0|socket@008e34ac.close
@asio|1532525799.550640|0|socket@008e345c.close
@asio|1532525799.551616|~8|
所以async_receive() #8
创建了最后一个,|<6|
io_context.stop()
调用了之后,然后我不知道如何获取error_code
fromyield_context
来调用处理程序。
问题#2 它甚至是异步读取数据块以收集整个数据包的正确方法吗?
解决方案
根据定义,io_context::stop
防止事件循环执行其他处理程序。所以没有办法让退出代码进入处理程序,因为它没有被调用。
您可能希望有一个“软停止”功能,您可以在其中停止向 io_context 承认新的异步任务,并可选择取消任何挂起的操作。
如果挂起的操作可能花费太长时间,您将需要添加一个截止时间计时器,该计时器强制在某个阈值时间间隔内取消。
使run
循环退出的常用方法是释放一个work
对象。见https://www.boost.org/doc/libs/1_67_0/doc/html/boost_asio/reference/io_context__work.html
推荐阅读
- vue.js - Vuetify v-spacer 没有效果
- arrays - CS50 / BEGINNER - C 中嵌套 for 循环中的分段错误
- javascript - 一旦用户已经将项目添加到列表中,如何禁用“添加”项目按钮?
- r - .jnew("edu/uic/ncdm/venn/data/VennData", as.character(combinations), 中的错误:
- python - 检查用户是否单击了 QTextBrowser 中的粗体文本?
- python - 我正在尝试在 python 中创建一个程序,该程序接受用户提供的输入并告诉他们他们是否未成年
- django - 如何使用 GraphQL 在 Django 文件系统中存储图像和视频
- java - Apache Camel 异常处理
- java - 在手动删除 RabbitMQ 后重新创建队列
- c++ - 模板特化的别名数据类型