从通过 boost::asio::co_spawn 启动的协同例程返回一个值

问题描述 投票:0回答:1

我有一些 asio 代码,用于从客户端传输文件。这段代码工作正常,如下:

bool FileTransferBehaviour::ConnectAndTransferFile(const std::string& _sender,
                                               const std::string& _filePath,
                                               size_t _numBytes)
{
  // use a coroutine to accept the connection and receive the file.
  bool result = false;

  asio::co_spawn(m_ioContext,
     [&result, &filePath, _numBytes, this]() mutable
      -> asio::awaitable<void> {
        auto maybeSock = co_await CoAwaitClientConnection();
        if (maybeSock.has_value()) {
            result = ReceiveFile(maybeSock.value(),                                               filePath, _numBytes);
        }
    }, asio::detached);

  m_ioContext.restart();
  m_ioContext.run();

  return result;
}

当前在内部 lambda 表达式中设置了

result
。我更愿意从协程返回这个结果,而不是通过引用捕获局部变量,即

bool FileTransferBehaviour::ConnectAndTransferFile(const std::string& _sender,
                                               const std::string& _filePath,
                                               size_t _numBytes)
{
  // use a coroutine to accept the connection and receive the file.
  bool result = co_await asio::co_spawn(m_ioContext,
     &filePath, _numBytes, this]() mutable
      -> asio::awaitable<bool> {
        auto maybeSock = co_await CoAwaitClientConnection();
        if (maybeSock.has_value()) {
            co_return ReceiveFile(maybeSock.value(),                                               filePath, _numBytes);
        }
        co_return false;
    }, asio::detached);

  m_ioContext.restart();
  m_ioContext.run();

  return result;
} 

当我更改 lambda 的返回类型时,代码失败并显示

FileTransferBehaviour.cpp(101,42): error C2228: left of '.await_ready' must have 
class/struct/union [MyProject,vcxproj]
FileTransferBehaviour.cpp(101,17): error C2440: 'initializing': cannot convert from 
'void' to 'bool' [MyProject.vcxproj]

我正在使用 C++20 和 CL 版本 19.37.32824 (Visual Studio 2022)

使用 GCC 11.4.0 我收到以下错误:

FileTransferBehaviour.cpp:101:19: error: unable to find the promise type for this coroutine
  101 |     bool result = co_await asio::co_spawn(m_ioContext,

我错过了什么?

c++ c++20 boost-asio c++-coroutine
1个回答
0
投票

在您的第一个版本中,

ConnectAndTransferFile
不是协程。它是一个生成协程的函数,该协程恰好在函数内定义为 lambda。该协程被移交给 ASIO,并且您的外部非协程本质上会等待它完成然后再返回。

这是同步操作。

在您的第二个版本中,您已将

ConnectAndTransferFile
更改为协程。这就是您直接在
co_await asio::co_spawn(...)
中执行
ConnectAndTransferFile
时发生的情况。

当然,如果一个函数是协程,那么它就不能

return
;它必须
co_return
它。此外,函数的签名现在需要指示要与该协程一起使用的 Promise 类型。这通常是使用返回值来完成的。就您而言,您可能希望它返回
asio::awaitable<bool>

但这意味着调用协程的代码必须等待它来提取

bool
结果。您的协程可能也不应该
restart
run
上下文。

© www.soinside.com 2019 - 2024. All rights reserved.