0

我正在使用 cpprestsdk 开发 CLIENT SERVER 应用程序,它工作正常。现在我想使用协同程序提高我的代码的可读性(很多 .then() 方法)。使用 co_await 编译器(在 VC++2015 或 VC++2017 上)将在“继续”中重构代码,摆脱 .then 语句。我试图理解 co_await 是如何工作的,但实际上我并没有完全理解。一般来说,如果我有这样的任务和延续:

client1.request(methods::GET, addr).then([=](http_response response)
{
    printf("Response status code %u returned.\n", response.status_code());

    if (response.status_code() == status_codes::OK)
    {
        wstring output = response.extract_utf16string().get();
        wcout << output << endl;
    }
 }).wait();

它变得容易

auto response = co_await client1.request(methods::GET, addr); 
printf("Response status code %u returned.\n", response.status_code()); 
if (response.status_code() == status_codes::OK) 
{ wstring output = response.extract_utf16string().get();
  wcout << output << endl; 
} 

我现在的问题是当我有这样的情况时:

 pplx::task UploadFileToHttpServerAsync()
 {
      using concurrency::streams::file_stream;
      using concurrency::streams::basic_istream;

      namespace some_namespace = web::http;


      // Open stream to file.
      wstring filePath = L"out.txt";
      return file_stream<unsigned char>::open_istream(filePath).then([=](pplx::task<basic_istream<unsigned char>> previousTask)
      {
          try
          {
               auto fileStream = previousTask.get();

               // Make HTTP request with the file stream as the body.
               http_client client(XMLReader::data.URL);

               return client.request(methods::POST, filePath, fileStream).then([fileStream](pplx::task<http_response> previousTask)
                   {

如果我有 return 语句,如何使用 co_await 重构我的代码?

4

1 回答 1

0

co_await等等背后的整个想法是你编写你的代码,就好像它是同步的。

如果stream<unsigned char>::open_istream是同步函数,它会返回什么?它会返回一个basic_istream<unsigned char>. 所以这就是co_await它会返回的内容(假设 co_await 机器存在pplx::task):

wstring filePath = L"out.txt";
basic_istream<unsigned char> fileStream = co_await file_stream<unsigned char>::open_istream(filePath);

从那里开始,您继续编写代码,就好像它是同步的:

// Make HTTP request with the file stream as the body.
http_client client(XMLReader::data.URL);

然后,你做这些co_await事情,继续编写你的代码,就好像它是完全同步的:

auto response = co_await client.request(methods::POST, filePath, fileStream);

然后你处理response你可能在你的不完整代码中的处理。

以 return 语句开头的唯一原因是因为这就是您手动执行延续的方式。每一层延续返回链中要继续的下一个任务,task::then捕获task并继续它。

有了co_await,你就不必费心了。您只是假装您正在编写同步代码并让编译器使其快速运行。

于 2017-06-21T17:11:41.510 回答