我想知道为什么将代码从Future
直接使用更改tokio::spawn
为使用async move
块可以编译代码。
直接使用:
struct ClientMsg {
...
resp: oneshot::Sender<Bytes>,
}
async fn client_thread(
mut rx: Receiver<ClientMsg>,
client: Client,
) -> Result<(), Box<dyn Error>> {
while let Some(msg) = rx.recv().await {
...
let response = client.get(url).send().await?.bytes().await?;
msg.resp.send(response).unwrap();
}
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
...
let (tx, rx) = mpsc::channel(5);
tokio::spawn(client_thread(rx, client)); // <--- Difference is here
Ok(())
}
异步块:
struct ClientMsg {
...
resp: oneshot::Sender<Bytes>,
}
async fn client_thread(
mut rx: Receiver<ClientMsg>,
client: Client,
) -> Result<(), Box<dyn Error>> {
while let Some(msg) = rx.recv().await {
...
let response = client.get(url).send().await?.bytes().await?;
msg.resp.send(response).unwrap();
}
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
...
let (tx, rx) = mpsc::channel(5);
tokio::spawn(async move { client_thread(rx, client) }); // <-- Difference is here
Ok(())
}
请注意以下事项use
:
use bytes::Bytes;
use reqwest::Client;
use tokio::sync::{
mpsc::{self, Receiver},
oneshot,
};
use url::Url;
直接使用代码失败并显示:
error[E0277]: `(dyn StdError + 'static)` cannot be sent between threads safely
--> src/main.rs:44:5
|
44 | tokio::spawn(client_thread(rx, client, base_url));
| ^^^^^^^^^^^^ `(dyn StdError + 'static)` cannot be sent between threads safely
|
::: /home/jeanluc/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.2.0/src/task/spawn.rs:130:20
|
130 | T::Output: Send + 'static,
| ---- required by this bound in `tokio::spawn`
|
= help: the trait `Send` is not implemented for `(dyn StdError + 'static)`
= note: required because of the requirements on the impl of `Send` for `Unique<(dyn StdError + 'static)>`
= note: required because it appears within the type `Box<(dyn StdError + 'static)>`
= note: required because it appears within the type `std::result::Result<(), Box<(dyn StdError + 'static)>>`
的返回类型与函数client_thread
完全相同main
,但是,在 Tokio 上运行没有任何问题。此外,来自implements的错误类型reqwest
Send
。