使用 cpprestsdk (casablanca) 和 asio 在应用程序中异步等待请求完成

Posted

技术标签:

【中文标题】使用 cpprestsdk (casablanca) 和 asio 在应用程序中异步等待请求完成【英文标题】:Async wait for request completion in app using cpprestsdk (casablanca) and asio 【发布时间】:2015-12-03 07:52:45 【问题描述】:

我使用 cpprestsdk(前卡萨布兰卡)和 Boost.Asio,在等待请求完成时我需要让步(用于其他任务)。

我用这个:

void client::make_request(boost::asio::yield_context yield)

    http_client client;
    uri = "http://example.com/uri";

    auto request_task = client.request(methods::GET, uri);

    boost::asio::deadline_timer yield_timer(io_service_);
    while (!request_task.is_done())
    
        // yield, for example for 10 ms
        yield_timer.expires_from_now(default_yield_time_);
        yield_timer.async_wait(yield);
    

    auto response = request_task.get();

    // ...
    // parse response, etc.
    // ...

有没有更优雅的方式(遗憾的是对我来说不是很明显 :-( )在不使用 asio 计时器的情况下做到这一点?

【问题讨论】:

@MikeMB 不,std::this_thread::wait_for 阻塞了整个系统线程,从而阻塞了 asio 任务的执行。 (Asio 使用它的线程池和系统线程来执行任务,类似于所谓的“绿色线程”。)简单地说,async_wait 表示 asio 调度程序从任务队列中运行其他任务,并在指定数量后返回当前任务时间。想象一下,你有 10 万个并发任务,你不能运行 10 万个系统线程,但是 asio 可以使用它的线程池(几乎)同时运行它们。 你的request_task 是什么? @PSIAlt 只是从互联网请求任何 uri 我明白了。你的request_task 类型是std::future 还是哪个类型?如果自定义,需要定义。 @PSIAlt 这是来自 cpprestsdk(卡萨布兰卡)图书馆的 pplx::task<web::http::http_response> 【参考方案1】:

我想你想要这样的东西:

void client::make_request(boost::asio::yield_context yield)

    http_client client;
    uri = "http://example.com/uri";

    client.request(methods::GET, uri)
        .then([](web::http::http_response response) 
        // ...
        // parse response, etc.
        // ...
    

我不确定你的屈服点。它应该是自动的。异步编程可能与我们习惯的方式不同。

【讨论】:

以上是关于使用 cpprestsdk (casablanca) 和 asio 在应用程序中异步等待请求完成的主要内容,如果未能解决你的问题,请参考以下文章

使用 C++ REST SDK (Casablanca) 从文件中读取 JSON

使用cpprestsdk将字符串转换为web :: json

将编译器命令行转换为 Casablanca Rest SDK 的 CMakeLists.txt

(原创)linux下Microsoft/cpprestsdk支持https(server)

在 win32 服务 (C++) 中生成 casablanca http_listener 的问题

微软开源 C++ REST SDK