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

The proper method to get tokio runtime handle based on current running environment

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

但是,当我将代码写为:

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 时,代码 运行s 成功。

我想我的 get_runtime_handle 函数有问题,正确的表达方式是什么? 完整的 运行 可用代码是 here

此外,当方法 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() 结束时被丢弃。如果函数创建一个,你应该 return 运行时。

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();
}