rust 如何在Future::poll()中睡觉?

thigvfpy  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(155)

我想在poll()中休眠1秒,但它卡在Pending中,据我所知,我传递了它&mut cx,它应该会在1秒后唤醒当前任务。

use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::{Duration};

struct MyDelay {}

impl Future for MyDelay {
    type Output = ();
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        println!("poll");
        let sleep = tokio::time::sleep(Duration::from_secs(1));
        tokio::pin!(sleep);
        sleep.poll(cx)
    }
}

#[tokio::main]
async fn main() {
    let delay = MyDelay{};
    let a = delay.await;
    dbg!(a);
}

播放网址:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ed6c09df100f1140ddc85b2ae600ab93

y53ybaqx

y53ybaqx1#

每一次投票都创造了一个新的Sleep未来,它从头开始。
相反,您应该将Sleep存储在您的未来中。使用pin-project-lite很容易:

pin_project_lite::pin_project! {
    struct MyDelay {
        #[pin]
        sleep: tokio::time::Sleep,
    }
}

impl MyDelay {
    fn new() -> Self {
        Self {
            sleep: tokio::time::sleep(Duration::from_secs(1)),
        }
    }
}

impl Future for MyDelay {
    type Output = ();
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        println!("poll");
        let this = self.project();
        this.sleep.poll(cx)
    }
}

Playground.
请注意,轮询的次数并不一定,并且可能不是常数。

相关问题