【问题标题】:Async wait for request completion in app using cpprestsdk (casablanca) and asio使用 cpprestsdk (casablanca) 和 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>

标签: c++ multithreading boost-asio casablanca


【解决方案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.
        // ...
    }
}

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

【讨论】: