Given an async function and it's corresponding future, lets say:
async fn foo() -> Result<i32, &'static str> {
// ...
}
let my_future = foo();
what is the difference between awaiting it using just .await other than using tokio::spawn().await?
// like this...
let result1 = my_future.await;
// ... and like this
let result2 = tokio::spawn(my_future).await;
Function tokio::spawnSpawns a new asynchronous task, returning a JoinHandle for it. Spawning a task enables the task to execute concurrently to other tasks. The spawned task may execute on the current thread, or it may be sent to a different thread to be executed.
Since blocking tasks are not async, each blocking thread can work on only one spawn_blocking task at the time. More blocking threads are spawned if more spawn_blocking tasks are spawned at the same time, up to some upper limit (which is around 500 by default).
A task is similar to an OS thread, but rather than being managed by the OS scheduler, they are managed by the Tokio runtime. Another name for this general pattern is green threads.
The poll method The core method of future, poll , is used to attempt to generate the value of a Future . This method does not block but is allowed to inform the caller that the value is not ready yet.
One typically doesn't await a spawned task (or at least not right away). It's more common to simply write:
tokio::spawn(my_future);
Leave out the .await
and the task will run in the background while the current task continues. Immediately calling .await
blocks the current task. spawn(task).await
is effectively no different than task.await
. It's akin to creating a thread and immediately joining it, which is equally pointless.
Spawned tasks don't need to be awaited the way bare futures do. Awaiting them is optional. When might one want to await one, then? If you want to block the current task until the spawned task finishes.
let task = tokio::spawn(my_future);
// Do something else.
do_other_work();
// Now wait for the task to complete, if it hasn't already.
task.await;
Or if you need the result, but need to do work in between starting the task and collecting the result.
let task = tokio::spawn(my_future);
// Do something else.
do_other_work();
// Get the result.
let result = task.await;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With