Tokio 错误:“没有正在运行的反应器”,即使安装了 #[tokio::main] 和单个版本的 tokio

Chr*_*ris 7 rust rust-tokio

当运行这样的代码时:

use futures::executor;
...
pub fn store_temporary_password(email: &str, password: &str) -> Result<(), Box<dyn Error>> {
  let client = DynamoDbClient::new(Region::ApSoutheast2);
  ...
  let future = client.put_item(input);
  executor::block_on(future)?; <- crashes here
  Ok(())
}
Run Code Online (Sandbox Code Playgroud)

我收到错误:

thread '<unnamed>' panicked at 'there is no reactor running, must be called from the context of a Tokio 1.x runtime
Run Code Online (Sandbox Code Playgroud)

我的 main 具有 tokio 注释,因为它应该是:

#[tokio::main]
async fn main() {
  ...
Run Code Online (Sandbox Code Playgroud)

我的 Cargo.toml 看起来像:

[dependencies]
...
futures = { version="0", features=["executor"] }
tokio = "1"
Run Code Online (Sandbox Code Playgroud)

我的 cars.lock 显示我只有 futures 和 tokio 的 1 个版本(分别为“1.2.0”和“0.3.12”)。

这耗尽了我在其他地方找到的对此问题的解释。有任何想法吗?谢谢。

Ibr*_*med 6

您必须在调用之前输入 tokio 运行时上下文block_on

let handle = tokio::runtime::Handle::current();
handle.enter();
executor::block_on(future)?;
Run Code Online (Sandbox Code Playgroud)

请注意,您的代码违反了异步函数不应花费很长时间而不到达.await. 理想情况下,store_temporary_password应该标记为async避免阻塞当前线程:

pub async fn store_temporary_password(email: &str, password: &str) -> Result<(), Box<dyn Error>> {
  ...
  let future = client.put_item(input);
  future.await?;
  Ok(())
}
Run Code Online (Sandbox Code Playgroud)

如果这不是一个选项,您应该包装任何调用 instore_temporary_passwordtokio::spawn_blocking在单独的线程池上运行阻塞操作。