Await multiple tasks spawned by tokio

tokio::task::spawn returns tokio::task::JoinHandle

pub async fn evaluate(self : Arc<Self>, par : Par) {

    let evaluators : Vec<ThreadSafeEvaluator>;
    evaluators = par.sends.into_iter().map( |s| s.into() )
        .chain( par.receives.into_iter().map( |r| r.into() ) )
        .collect();


    let mut handles = Vec::new();

    for (_idx, evaluator) in evaluators.into_iter().enumerate() {
        let cloned_self = self.clone();
        handles.push(
            task::spawn( async move {
                evaluator.evaluate(cloned_self).await;
            })
        );
    }
}

If I can wait for all the tasks completion, I dont need wrap Self with Arc.

How can I await (not blocking wait) all the handles ?

Full source code can be found here

Thanks in advance

This should do it.

for handle in handles {
    let output = handle.await.expect("Panic in task");
}
1 Like

I'm sure you're aware of it @alice but people have to be very careful when doing that, because what that does is wait for each handle Future to finish before starting the next one, which is different to what happens in JavaScript. If you want them to happen in parallel, you need to use join.

These particular futures are handles from task::spawn(), though, which starts the Future it was given as an argument immediately.

1 Like

Yeah, the point is that the tasks are spawned. They started running when you spawned them. A JoinHandle lets you wait for the task to finish, but awaiting the handle has no effect on whether the task runs or not, it will run either way.

3 Likes