如何调用处理程序?

时间:2018-07-25 13:54:47

标签: c++ boost asio

如果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中调用yield_context进行调用处理程序。

问题#2甚至是异步读取大块数据以收集整个数据包的正确方法吗?

1 个答案:

答案 0 :(得分:0)

根据定义,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