Struct TaskHandle

Source
pub struct TaskHandle<T>(pub JoinHandle<T>);
Expand description

TaskHandle is simple wrapper around Tokio task::JoinHandle that aborts tasks on Handle drop. The easiest way to obtain TaskHandle is importing TaskExt trait and running to_task_handle() on Tokio task::JoinHandle.

§Example

let (tx, mut rx) = mpsc::channel(20);
let handle =
    tokio::spawn(async move { while let Some(_) = rx.recv().await {} }).to_task_handle();

let r = tx.send(true).await;
// drop handle so the inner task is aborted
drop(handle);

// sadly seems like we need to wait so Tokio runtime has time to actually drop all variables
sleep(Duration::from_millis(1)).await;
let r = tx.send(false).await;
assert!(r.is_err(), "'rx' along with task inside 'handle' should be dropped at this point so tx.send fails");

Tuple Fields§

§0: JoinHandle<T>

Methods from Deref<Target = JoinHandle<T>>§

Source

pub fn abort(&self)

Abort the task associated with the handle.

Awaiting a cancelled task might complete as usual if the task was already completed at the time it was cancelled, but most likely it will fail with a cancelled JoinError.

Be aware that tasks spawned using spawn_blocking cannot be aborted because they are not async. If you call abort on a spawn_blocking task, then this will not have any effect, and the task will continue running normally. The exception is if the task has not started running yet; in that case, calling abort may prevent the task from starting.

See also the module level docs for more information on cancellation.

use tokio::time;

let mut handles = Vec::new();

handles.push(tokio::spawn(async {
   time::sleep(time::Duration::from_secs(10)).await;
   true
}));

handles.push(tokio::spawn(async {
   time::sleep(time::Duration::from_secs(10)).await;
   false
}));

for handle in &handles {
    handle.abort();
}

for handle in handles {
    assert!(handle.await.unwrap_err().is_cancelled());
}
Source

pub fn is_finished(&self) -> bool

Checks if the task associated with this JoinHandle has finished.

Please note that this method can return false even if abort has been called on the task. This is because the cancellation process may take some time, and this method does not return true until it has completed.

use tokio::time;

let handle1 = tokio::spawn(async {
    // do some stuff here
});
let handle2 = tokio::spawn(async {
    // do some other stuff here
    time::sleep(time::Duration::from_secs(10)).await;
});
// Wait for the task to finish
handle2.abort();
time::sleep(time::Duration::from_secs(1)).await;
assert!(handle1.is_finished());
assert!(handle2.is_finished());
Source

pub fn abort_handle(&self) -> AbortHandle

Returns a new AbortHandle that can be used to remotely abort this task.

Awaiting a task cancelled by the AbortHandle might complete as usual if the task was already completed at the time it was cancelled, but most likely it will fail with a cancelled JoinError.

use tokio::{time, task};

let mut handles = Vec::new();

handles.push(tokio::spawn(async {
   time::sleep(time::Duration::from_secs(10)).await;
   true
}));

handles.push(tokio::spawn(async {
   time::sleep(time::Duration::from_secs(10)).await;
   false
}));

let abort_handles: Vec<task::AbortHandle> = handles.iter().map(|h| h.abort_handle()).collect();

for handle in abort_handles {
    handle.abort();
}

for handle in handles {
    assert!(handle.await.unwrap_err().is_cancelled());
}
Source

pub fn id(&self) -> Id

Returns a task ID that uniquely identifies this task relative to other currently spawned tasks.

Trait Implementations§

Source§

impl<T: Debug> Debug for TaskHandle<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Deref for TaskHandle<T>

Source§

type Target = JoinHandle<T>

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<T> Drop for TaskHandle<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<T> Freeze for TaskHandle<T>

§

impl<T> RefUnwindSafe for TaskHandle<T>

§

impl<T> Send for TaskHandle<T>
where T: Send,

§

impl<T> Sync for TaskHandle<T>
where T: Send,

§

impl<T> Unpin for TaskHandle<T>

§

impl<T> UnwindSafe for TaskHandle<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.