根据当前运行环境获取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();
}