如何在结构体中使用静态的FuturesUnordered?
如何在结构体中使用静态的FuturesUnordered?
嘿,我来帮你搞定在结构体里使用FuturesUnordered的问题!你原来的代码是直接在main函数里处理定时任务和异步任务队列,现在我们把这套逻辑封装到结构体中,让FuturesUnordered成为结构体的一个字段,这样就能更优雅地管理任务队列啦。
首先,我们需要定义一个结构体来持有FuturesUnordered实例和定时用的Interval,然后给结构体实现初始化、添加任务和运行循环的方法。完整代码如下:
use std::time::Duration; use tokio::time::Interval; use futures::stream::FuturesUnordered; use futures::FutureExt; // 用于转换为BoxFuture struct TaskManager { interval: Interval, tasks: FuturesUnordered<BoxFuture<'static, ()>>, } impl TaskManager { // 初始化TaskManager fn new() -> Self { Self { interval: tokio::time::interval(Duration::from_secs(1)), tasks: FuturesUnordered::new(), } } // 给任务队列添加新的异步任务 fn add_task(&mut self, task: impl std::future::Future<Output = ()> + 'static + Send) { self.tasks.push(task.boxed()); } // 启动任务管理的主循环 async fn run(mut self) { loop { tokio::select! { _ = self.interval.tick() => { // 每秒触发一次,这里替换成你实际的任务添加逻辑 self.add_task(async { println!("新任务开始执行..."); tokio::time::sleep(Duration::from_millis(500)).await; println!("这个任务完成啦!"); }); }, Some(_) = self.tasks.next() => { // 有任务执行完成时触发,这里可以处理任务结果 println!("检测到一个任务已经完成"); }, // 你可以在这里加退出条件,比如监听终止信号,这里先简化处理 } } } } #[tokio::main] async fn main() { let mut manager = TaskManager::new(); // 先添加几个初始测试任务 manager.add_task(async { println!("初始任务1启动"); tokio::time::sleep(Duration::from_secs(2)).await; }); manager.add_task(async { println!("初始任务2启动"); tokio::time::sleep(Duration::from_secs(3)).await; }); // 启动任务管理器 manager.run().await; }
这里有几个需要注意的小细节:
- 我们用
BoxFuture<'static, ()>作为FuturesUnordered的泛型参数,因为结构体的生命周期和任务的生命周期需要兼容,'static能确保任务可以一直存在直到执行完成。 add_task方法接受任何实现了Future的类型,通过boxed()把它转换成BoxFuture,这样就能顺利存入FuturesUnordered队列中。- 原来的循环逻辑被封装到了
run方法里,main函数只需要负责创建实例、添加初始任务,然后启动运行即可,代码结构会清晰很多。
备注:内容来源于stack exchange,提问作者Leibale Eidelman
相关产品推荐
相关产品推荐

