使用 yield_context
作为堆栈协程中 Asio 异步操作的处理程序非常棒!但是 ip::basic_resolver::async_resolve
的处理程序具有与简单地接收错误代码不同的签名(我很好奇为什么它不将 resolver::iterator &
作为 async_resolve
中的参数,就像 basic_socket<Protocol1, SocketService> &
中的 basic_socket_acceptor::async_accept
参数一样) ).有没有办法使用 yield
作为它的处理者?
同样的问题也适用于 async_connect
.
最佳答案
如 Stackful Coroutines overview 中所述,当通过 yield_context
作为 initiating function 的处理程序其异步操作的处理程序具有以下形式:
void handler(boost::system::error_code ec, result_type result);
启动函数将返回result_type
。在这种情况下,basic_resolver::async_resolve()
的处理程序类型要求是 ResolverHandler ,其形式为:
void resolve_handler(
const boost::system::error_code& ec,
boost::asio::ip::tcp::resolver::iterator iterator)
因此,basic_resolver::async_resolve(..., yield_context)
将返回 resolver::iterator
。
这是一个完整的最小示例,展示了这种行为:
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
int main()
{
boost::asio::io_service io_service;
boost::asio::spawn(io_service,
[&](boost::asio::yield_context yield)
{
using tcp = boost::asio::ip::tcp;
tcp::resolver resolver(io_service);
// The async_resolve initiating function will return an iterator, as
// a yield_context is being passed as a handler.
tcp::resolver::iterator iterator = resolver.async_resolve(
tcp::resolver::query("www.google.com", "80"), yield);
// Iterator over endpoints.
for(tcp::resolver::iterator end; iterator != end; ++iterator)
{
std::cout << iterator->endpoint().address().to_string() << std::endl;
}
});
io_service.run();
}
输出:
74.125.227.209
74.125.227.210
74.125.227.211
74.125.227.212
74.125.227.208
2607:f8b0:4000:80a::1012
关于c++ - 如何使用 yield_context 作为 resolver.async_resolve 的处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25298572/