async-await - 如何在 Tokio 中使用 async/await 语法?

标签 async-await rust rust-tokio

我正在尝试对 Rust 中的进程使用 async/await。我正在使用 tokiotokio-process:

#![feature(await_macro, async_await, futures_api)]

extern crate tokio;
extern crate tokio_process;

use std::process::Command;
use tokio_process::CommandExt;

fn main() {
    tokio::run_async(main_async());
}

async fn main_async() {
    let out = Command::new("echo")
        .arg("hello")
        .arg("world")
        .output_async();
    let s = await!(out);
}

这是我得到的错误:

error[E0277]: the trait bound `tokio_process::OutputAsync: std::future::Future` is not satisfied
  --> src/main.rs:21:13
   |
21 |     let s = await!(out);
   |             ^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `tokio_process::OutputAsync`
   |
   = note: required by `std::future::poll_with_tls_waker`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0277]: the trait bound `tokio_process::OutputAsync: std::future::Future` is not satisfied
  --> src/main.rs:21:13
   |
21 |     let s = await!(out);
   |             ^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `tokio_process::OutputAsync`
   |
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

我该如何做对?

最佳答案

TL;DR:使用 Tokio 0.2 或更新版本,它应该可以正常工作。

Tokio 0.1 和相关的 crate 是使用 futures 0.1 crate 实现的。 Future这个 crate 的特征在概念上类似于 Future 的版本来自标准库的特征,但在细节上有很大不同。 async/await语法是围绕标准库中特征的版本构建的。

Tokio 0.2 和相关的 crate 是使用标准库实现的 Future并进行了重新设计以更好地支持 async/await语法。

东京0.2

[dependencies]
tokio = { version = "0.2", features = ["full"] }
use tokio::process::Command;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let out = Command::new("echo")
        .arg("hello")
        .arg("world")
        .output()
        .await?;

    let s = String::from_utf8_lossy(&out.stdout);

    println!("{}", s);
    Ok(())
}
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.05s
     Running `target/debug/tokio2`
hello world

测试:

  • Rustc 1.39.0

东京0.1

你必须 translate between a Future implemented against the trait from the futures 0.1 crate and from the standard library .此外,您需要启动 Tokio 运行时服务,对于 Tokio 0.1 和 Tokio 0.3 来说都是理想的选择。那就是tokio-compat进来:

[dependencies]
futures = { version = "0.3", features = ["compat"] }
tokio-compat = "0.1"
tokio-process = "0.2"
use futures::compat::Future01CompatExt;
use std::process::Command;
use tokio_process::CommandExt;

fn main() {
    tokio_compat::run_std(main_async());
}

async fn main_async() {
    let out = Command::new("echo")
        .arg("hello")
        .arg("world")
        .output_async();

    // Convert future from 0.1 to 0.3
    let s = out.compat().await;

    println!("{:?}", s);
}
% cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.07s
     Running `target/debug/tt`
Ok(Output { status: ExitStatus(ExitStatus(0)), stdout: "hello world\n", stderr: "" })

使用 Rust 1.43.0 测试

另见:

关于async-await - 如何在 Tokio 中使用 async/await 语法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54853917/

相关文章:

c# - 没有多线程异步/等待的并发

Rust - 为什么借用 &mut 两次时它不会给我一个错误

rust - 找不到命令: wrangler

rust - 如果 `char` 不能容纳 >=256 的数字,我该如何使用 libTCOD 图形 block ?

rust - rust目前有类似JavaScript的setTimeout和setInterval的库实现功能吗?

multithreading - rust tokio::spawn 在 mutexguard 之后等待

c# - 带有 await 的异步 lambda 表达式返回任务?

时间:2019-03-17 标签:c#asyncawait

c# - 使用 FileStream.WriteAsync() 时,再次调用该方法时会发生什么

rust - Tokio 任务可以优雅地终止整个运行时吗?