Function zng::task::run

source ·
pub async fn run<R, T>(task: impl IntoFuture<IntoFuture = T>) -> R
where R: Send + 'static, T: Future<Output = R> + Send + 'static,
Expand description

Spawn a parallel async task that can also be .await for the task result.

§Parallel

The task runs in the primary rayon thread-pool, every poll happens inside a call to rayon::spawn.

You can use parallel iterators, join or any of rayon’s utilities inside task to make it multi-threaded, otherwise it will run in a single thread at a time, still not blocking the UI.

The rayon crate is re-exported in task::rayon for convenience and compatibility.

§Async

The task is also a future so you can .await, after each .await the task continues executing in whatever rayon thread is free, so the task should either be doing CPU intensive work or awaiting, blocking IO operations block the thread from being used by other tasks reducing overall performance. You can use wait for IO or blocking operations and for networking you can use any of the async crates, as long as they start their own event reactor.

The task lives inside the Waker when awaiting and inside rayon::spawn when running.

§Examples

async fn on_event(&mut self) {
    self.sum = task::run(async {
        read_numbers().await.par_iter().map(|i| i * i).sum()
    }).await;
}

The example .await for some numbers and then uses a parallel iterator to compute a result, this all runs in parallel because it is inside a run task. The task result is then .await inside one of the UI async tasks. Note that the task captures the caller LocalContext so you can interact with variables and UI services directly inside the task too.

§Cancellation

The task starts running immediately, awaiting the returned future merely awaits for a message from the worker threads and that means the task future is not owned by the returned future. Usually to cancel a future you only need to drop it, in this task dropping the returned future will only drop the task once it reaches a .await point and detects that the result channel is disconnected.

If you want to deterministically known that the task was cancelled use a cancellation signal.

§Panic Propagation

If the task panics the panic is resumed in the awaiting thread using resume_unwind. You can use run_catch to get the panic as an error instead.