Synchronously check return value from JoinHandle in Tokio

I spawn a tokio task, and take its return value once it has finished:

fn main() {
    let rt = tokio::runtime::Runtime::new().unwrap();

    let mut join_handle = rt.spawn(async {
        tokio::time::sleep(std::time::Duration::from_secs(5)).await;
        "Done"
    });

    // GUI paint loop
    loop {
        // Paint a GUI on every frame...

        // If task finished, display it in the GUI
        if join_handle.is_finished() {
            let return_value = rt.block_on(&mut join_handle).unwrap();
            println!("Return value: {}", &return_value);
        }
    }
}

This successfully prints the return value from join_handle, but then it panics:

Return value: Done
thread 'main' panicked at tokio-1.39.2/src/runtime/task/core.rs:375:22:
JoinHandle polled after completion

Why does tokio panic, and how can I get around it?

You tried to block_on() the same future twice. Apparently that's not supported.

You're right, I can't believe I didn't spot this basic mistake :person_facepalming:. Here's a trivially corrected version of my code:

fn main() {
    let rt = tokio::runtime::Runtime::new().unwrap();

    let mut join_handle_option = Some(rt.spawn(async {
        tokio::time::sleep(std::time::Duration::from_secs(5)).await;
        "Done"
    }));

    // GUI paint loop
    loop {
        // Paint a GUI on every frame...

        // If task finished, display it in the GUI
        if let Some(join_handle) = &mut join_handle_option {
            if join_handle.is_finished() {
                let return_value = rt.block_on(join_handle).unwrap();
                println!("Return value: {}", &return_value);
                join_handle_option = None;
            }
        }
    }
}

I don't think this question is very helpful, so feel free to delete it (I don't have permissions to).

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.