跳到主要内容

JoinHandle

搜索

结构体 JoinHandle 

Source
pub struct JoinHandle<T> { /* private fields */ }
展开描述

用于 join 一个任务(await 其终止)的 owned 权限。

这可以看作是 Tokio 任务(而非线程)版本等价于 std::thread::JoinHandle 的类型。请注意,当你调用 spawn 时与此 JoinHandle 关联的后台任务会立即开始运行,即使你尚未 await 该 JoinHandle

JoinHandle 被丢弃时,与其关联的任务会被分离(detached),这意味着该任务不再有任何 handle,也无法再 join 它。

structtask::spawntask::spawn_blocking 函数创建。

可以保证:在通过 JoinHandle awaitJoinHandle::is_finishedAbortHandle::is_finished 观察到任务完成之前,已派生任务的析构函数已经运行结束。

§Cancel safety

&mut JoinHandle<T> 类型是 cancel safe 的。如果它在 tokio::select! 语句中作为事件,且其他分支先完成,可以保证任务的输出不会丢失。

如果 JoinHandle 被丢弃,则任务将继续在后台运行,其返回值将丢失。

§示例

通过 task::spawn 创建:

use tokio::task;

let join_handle: task::JoinHandle<_> = task::spawn(async {
    // some work here
});

通过 task::spawn_blocking 创建:

use tokio::task;

let join_handle: task::JoinHandle<_> = task::spawn_blocking(|| {
    // some blocking work here
});

JoinHandle<T> 中的泛型参数 T 表示已派生任务的返回类型。如果返回值是 i32,则该 join handle 的类型为 JoinHandle<i32>

use tokio::task;

let join_handle: task::JoinHandle<i32> = task::spawn(async {
    5 + 3
});

如果任务没有返回值,则该 join handle 的类型为 JoinHandle<()>

use tokio::task;

let join_handle: task::JoinHandle<()> = task::spawn(async {
    println!("I return nothing.");
});

请注意,handle.await 不会直接返回任务的返回类型。它会被包装在 Result 中,因为已派生任务中的 panic 会被 Tokio 捕获。要提取返回的值,需要双层链式使用 ? 操作符:

use tokio::task;
use std::io;

let join_handle: task::JoinHandle<Result<i32, io::Error>> = tokio::spawn(async {
    Ok(5 + 3)
});

let result = join_handle.await??;
assert_eq!(result, 8);
Ok(())

如果任务 panic,则错误为包含 panic 信息的 JoinError

use tokio::task;
use std::io;
use std::panic;

#[tokio::main]
async fn main() -> io::Result<()> {
    let join_handle: task::JoinHandle<Result<i32, io::Error>> = tokio::spawn(async {
        panic!("boom");
    });

    let err = join_handle.await.unwrap_err();
    assert!(err.is_panic());
    Ok(())
}

子任务被分离且存活时间超过其父任务:

use tokio::task;
use tokio::time;
use std::time::Duration;

let original_task = task::spawn(async {
    let _detached_task = task::spawn(async {
        // Here we sleep to make sure that the first task returns before.
        time::sleep(Duration::from_millis(10)).await;
        // This will be called, even though the JoinHandle is dropped.
        println!("♫ Still alive ♫");
    });
});

original_task.await.expect("The task being joined has panicked");
println!("Original task is joined.");

// We make sure that the new task has time to run, before the main
// task returns.

time::sleep(Duration::from_millis(1000)).await;

实现§

Source§

impl<T> JoinHandle<T>

Source

pub fn abort(&self)

终止与此 handle 关联的任务。

等待一个被取消的任务,如果该任务在被取消时已经完成,则可能会正常完成;但大多数情况下,它会因 取消 而失败并返回 JoinError

请注意,使用 spawn_blocking 派生的任务无法被终止,因为它们不是异步的。如果你对 spawn_blocking 任务调用 abort,则不会产生任何效果,任务将继续正常运行。例外情况是该任务尚未开始运行;此时调用 abort 可能会阻止该任务启动。

另请参阅 模块级文档 以获取有关取消的更多信息。

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

检查与此 JoinHandle 关联的任务是否已完成。

请注意,即使任务上已调用了 abort,此方法也可能返回 false。这是因为取消过程可能需要一些时间,只有在取消完成后此方法才会返回 true

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

返回一个新的 AbortHandle,可用于远程终止此任务。

等待被 AbortHandle 取消的任务,如果该任务在被取消时已经完成,则可能会正常完成;但大多数情况下,它会因 取消 而失败并返回 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

返回一个相对其他当前已派生任务能唯一标识此任务的 task ID

Trait 实现§

Source§

impl<T> Debug for JoinHandle<T>
where T: Debug,

Source§

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

使用给定的格式化器格式化此值。 更多信息
Source§

impl<T> Drop for JoinHandle<T>

Source§

fn drop(&mut self)

执行此类型的析构函数。 更多信息
Source§

impl<T> Future for JoinHandle<T>

Source§

type Output = Result<T, JoinError>

Future 完成时产生的值的类型。
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. 更多信息
Source§

impl<T> RefUnwindSafe for JoinHandle<T>

Source§

impl<T: Send> Send for JoinHandle<T>

Source§

impl<T: Send> Sync for JoinHandle<T>

Source§

impl<T> Unpin for JoinHandle<T>

Source§

impl<T> UnwindSafe for JoinHandle<T>

自动 Trait 实现§

§

impl<T> Freeze for JoinHandle<T>

§

impl<T> UnsafeUnpin for JoinHandle<T>

Blanket 实现§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. 更多信息
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. 更多信息
Source§

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

Source§

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

Mutably borrows from an owned value. 更多信息
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

原样返回传入的参数。

Source§

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

Source§

fn into(self) -> U

调用 U::from(self)

也就是说,此转换的具体行为取决于 From<T> for U 的实现方式。

Source§

impl<F> IntoFuture for F
where F: Future,

Source§

type Output = <F as Future>::Output

Future 完成时产生的输出。
Source§

type IntoFuture = F

我们将要把此值转变成哪种 future?
Source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. 更多信息
Source§

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

Source§

type Error = Infallible

转换出错时返回的类型。
Source§

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

执行转换。
Source§

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

Source§

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

转换出错时返回的类型。
Source§

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

执行转换。