根据当前运行环境获取tokio运行时句柄的正确方法



根据当前运行环境获取tokio运行时句柄的惯用方法是什么?

  • 对于已经在东京运行的方法,我想使用Handle.try_current().unwrap()来获取当前的方法。
  • 对于没有在东京运行的方法,我可以创建一个新的:Runtime::new().unwrap().handle()

然而,当我把我的代码写成:

fn get_runtime_handle() -> Handle {
match Handle::try_current() {
Ok(h) => h,
Err(_) => Runtime::new().unwrap().handle().clone(),
}
}
async fn a_async() -> Result<()> {
....
}
fn a() -> Result<()> {
let handle = get_runtime_handle();
handle.block_one (async { a_async().await; })
}
fn main() -> Result<()> {
a();
Ok(())
}

内部调用tokio::fs::read_dir,代码与Error: Custom { kind: Other, error: "background task failed" }一起崩溃。

当我在main中用Runtime::new().unwrap().handle().block_on替换handle.block_on时,代码运行成功。

我想我的get_runtime_handle函数是有问题的,什么是正确的方式来表达这个?完整的可运行代码在这里。

此外,当方法get_runtime_handle在tokio运行时内运行时,项目中的其他单元测试会报错:

thread 'main' panicked at 'Cannot start a runtime from within a runtime. 
This happens because a function (like `block_on`) attempted to block the
current thread while the thread is being used to drive asynchronous tasks.

问题是新运行时的生命周期,它在get_runtime_handle()的末尾被删除。如果函数创建了一个运行时,则应该返回运行时。

use tokio::runtime::{Runtime, Handle};
fn get_runtime_handle() -> (Handle, Option<Runtime>) {
match Handle::try_current() {
Ok(h) => (h, None),
Err(_) => {
let rt = Runtime::new().unwrap();
(rt.handle().clone(), Some(rt))
}
}

fn main() {
// let _ = Runtime::new().unwrap();
let (handle, rt) = get_runtime_handle();
}

最新更新