.await
操作并不总是要求 Future
对象实现 Unpin
,但如果一个 Future
对象没有 Unpin
特性,必须使用固定(Pin
)的方式来安全地进行异步操作。
以下这段因为Sleep是!unpin的,而且Box<Sleep>不是!unpin的,因此必须用pin包付起来,否则无法通过编译。
use std::future::Future;
use std::pin::Pin;
use std::time::Instant;
use tokio::time::{sleep, Duration};
// Trait for a sleeper with a synchronous `sleep` method
trait Sleeper {
fn sleep(&self) ->Box<dyn Future<Output = ()>>;
}
struct FixedSleeper {
sleep_ms: u64,
}
impl Sleeper for FixedSleeper {
fn sleep(&self) -> Box<dyn Future<Output=()>> {
Box::new(sleep(Duration::from_millis(self.sleep_ms)))
}
}
async fn run_all_sleepers_multiple_times(
sleepers: Vec<Box<dyn Sleeper>>,
n_times: usize,
) {
for _ in 0..n_times {
println!("running all sleepers..");
for sleeper in &sleepers {
let start = Instant::now();
sleeper.sleep().await;
println!("slept for {}ms", start.elapsed().as_millis());
}
}
}
#[tokio::main]
async fn main() {
let sleepers: Vec<Box<dyn Sleeper>> = vec![
Box::new(FixedSleeper { sleep_ms: 50 }),
Box::new(FixedSleeper { sleep_ms: 100 }),
];
run_all_sleepers_multiple_times(sleepers, 5).await;
}