有没有办法在新线程上启动tokio :: Delay以允许主循环继续?

时间:2019-01-20 19:10:40

标签: rust future rust-tokio

如果计时器没有取消,我试图在延迟结束时运行一个函数。用例是按住并双击以供用户输入。

我遇到的主要问题是tokio::run(task);阻止了主循环的执行,从而使我无法评估用户控件的状态。

fn start_timer(&self) {
    let function_name = self.combo.function_name.clone();
    let when = Instant::now() + Duration::from_millis(self.combo.timer_value as u64);
    let task = Delay::new(when)
        .and_then(move |_| {
            call_function(&function_name, InteropParams::Button);
            Ok(())
        })
        .map_err(|e| panic!("delay errored; err={:?}", e));

    tokio::run(task);
}

1 个答案:

答案 0 :(得分:2)

是的,您可以启动一个新的OS级别线程并在其中运行Tokio事件循环:

use futures::future::Future; // 0.1.25
use std::{
    thread,
    time::{Duration, Instant},
};
use tokio::timer::Delay; // 0.1.14 

fn main() {
    let t = thread::spawn(|| {
        let when = Instant::now() + Duration::from_millis(100);
        let task = Delay::new(when)
            .and_then(move |_| {
                println!("Delay expired");
                Ok(())
            })
            .map_err(|e| panic!("delay errored: {}", e));

        tokio::run(task);
    });

    t.join().unwrap();
}

您还可以通过tokio::spawn使用Tokio的任务:

use futures::future::{self, Future}; // 0.1.25
use std::time::{Duration, Instant};
use tokio::timer::Delay; // 0.1.14

fn main() {
    tokio::run(future::lazy(|| {
        tokio::spawn({
            let when = Instant::now() + Duration::from_millis(100);
            Delay::new(when)
                .and_then(move |_| {
                    println!("Delay 100 expired");
                    Ok(())
                })
                .map_err(|e| panic!("delay errored: {}", e))
        });

        tokio::spawn({
            let when = Instant::now() + Duration::from_millis(200);
            Delay::new(when)
                .and_then(move |_| {
                    println!("Delay 200 expired");
                    Ok(())
                })
                .map_err(|e| panic!("delay errored: {}", e))
        });

        future::ok::<_, ()>(())
    }))
}