使用yield_context
作为堆栈协程中Asio异步操作的处理程序真棒!但是ip::basic_resolver::async_resolve
的处理程序与仅仅接收错误代码的签名不同(我很好奇为什么它不会将resolver::iterator &
作为async_resolve
中的参数,比如basic_socket_acceptor::async_accept
中的basic_socket<Protocol1, SocketService> &
参数。有没有办法使用yield
作为它的处理程序?
同样的问题也适用于async_connect
。
答案 0 :(得分:5)
如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