You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在结构体中使用静态的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 17:33:01