我已经开始了多项任务,tokio::spawn
我想收集他们退出的原因dyn std::error::Error
。
如果任何任务恐慌,我想立即转发恐慌而不等待其他任务。为了实现这一点,我曾经在传播恐慌时futures::map
展开。tokio::JoinHandle
然后我过去常常tokio::join!
同时等待所有期货。
use futures::FutureExt;
#[tokio::main]
async fn main() {
tokio::spawn(async move {
foo().await;
})
.await
.unwrap();
}
async fn foo() {
// Start two tasks.
let worker1 = tokio::spawn(bar(1)).map(|res| res.unwrap());
let worker2 = tokio::spawn(bar(2)).map(|res| res.unwrap());
// Wait for all started tasks at once.
// This doesn't compile.
let (error1, error2) = tokio::join!(worker1, worker2);
// This does compile, but panics only after 5 seconds.
// let error1 = worker1.await;
// let error2 = worker2.await;
// Ignore in this example.
let _: Box<dyn std::error::Error + Send> = error1;
let _: Box<dyn std::error::Error + Send> = error2;
}
async fn bar(id: u8) -> Box<dyn std::error::Error + Send> {
if id == 1 {
tokio::time::sleep(core::time::Duration::from_secs(5)).await;
Box::new(std::io::Error::last_os_error())
} else {
panic!("Not yet implemented");
}
}
它给了我一个编译错误:
error: implementation of `FnOnce` is not general enough
--> src/main.rs:5:5
|
5 | tokio::spawn(async move {
| ^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(Result<Box<(dyn std::error::Error + std::marker::Send + '0)>, JoinError>) -> Box<dyn std::error::Error + std::marker::Send>` must implement `FnOnce<(Result<Box<(dyn std::error::Error + std::marker::Send + '1)>, JoinError>,)>`, for any two lifetimes `'0` and `'1`...
= note: ...but it actually implements `FnOnce<(Result<Box<dyn std::error::Error + std::marker::Send>, JoinError>,)>`
我正在与rustc 1.56.1 (59eed8a2a 2021-11-01)
. 我的 Cargo.toml 有:
tokio = { version = "1.12", features = ["full"] }
futures = "0.3"
我希望了解此错误或至少找到替代解决方案。