在 Boost 1.66 上,Asio 已经弃用了asio_handler_is_continuation
hook 函数,促进了defer
函数的使用。似乎该 函数的行为与asio_handler_is_continuation==true 时defer
的行为完全相同。post
但是,使用方式与使用defer
方式不同asio_handler_is_continuation
,我不知道如何正确使用defer
。
编辑:我认为下面的示例过于冗长,无法清楚地表达我的意思。这是较短的示例:
async_read_until(stream, read_buffer, "\r\n",
[](boost::system::error_code ec, std::size_t bytes_transferred)
{
if(!ec)
async_write(stream, write_buffer, some_handler);
})
现在async_read_until
完成后,传递的 lambda 处理程序将使用与boost::asio::post
. 但是async_write
在 lambda 处理程序内部是上一个异步任务的延续,所以我想调用 lambda 处理程序来利用defer
优化。
在上面的示例中,有什么方法可以使用defer
(而不是post
)调用 lambda 处理程序?
原始帖子:我正在尝试编写一个async_echo
类似于野兽文档中的简单启动函数,除了调用的部分boost::asio::async_write
将被称为延续。为了实现这一点,之前boost::asio::async_read_until
的中间操作必须调用处理程序*this
作为延续。
这是我在野兽文档的 async_echo 示例中所指的部分:
template<class AsyncStream, class Handler>
void echo_op<AsyncStream, Handler>::
operator()(boost::beast::error_code ec, std::size_t bytes_transferred)
{
// Store a reference to our state. The address of the state won't
// change, and this solves the problem where dereferencing the
// data member is undefined after a move.
auto& p = *p_;
// Now perform the next step in the state machine
switch(ec ? 2 : p.step)
{
// initial entry
case 0:
// read up to the first newline
p.step = 1;
return boost::asio::async_read_until(p.stream, p.buffer, "\r", std::move(*this));
case 1:
// write everything back
p.step = 2;
// async_read_until could have read past the newline,
// use buffers_prefix to make sure we only send one line
return boost::asio::async_write(p.stream,
boost::beast::buffers_prefix(bytes_transferred, p.buffer.data()), std::move(*this));
case 2:
p.buffer.consume(bytes_transferred);
break;
}
// Invoke the final handler. The implementation of `handler_ptr`
// will deallocate the storage for the state before the handler
// is invoked. This is necessary to provide the
// destroy-before-invocation guarantee on handler memory
// customizations.
//
// If we wanted to pass any arguments to the handler which come
// from the `state`, they would have to be moved to the stack
// first or else undefined behavior results.
//
p_.invoke(ec);
return;
}
在 1.66 之前的日子里,我可以简单地挂钩函数,如下所示:
template <Function, Handler>
friend bool asio_handler_is_continuation(echo_op<Function, Handler>* handler)
{
using boost::asio::asio_handler_is_continuation;
return handler.p_->step == 1 ||
asio_handler_is_continuation(std::addressof(handler.p_->handler()));
}
在echo_op
.
从 Boost 1.66 开始,上面的代码不太可能有任何效果(没有BOOST_ASIO_NO_DEPRECATION
宏)。所以我应该使用defer
.
但是由于boost::asio::async_read_until
保证“处理程序的调用将以等效于使用 boost::asio::io_context::post(). 的方式执行”,*this
因此不会使用 调用defer
,即作为延续。
是否有任何解决方法可以boost::asio::async_read_until
使用调用处理程序defer
?有没有利用defer
函数的好例子?