如何在不实现"发送"特性的第三方机箱中使用"tokio::spawn"



Oracle机箱中名为ResultSet的结构未实现Send特性。但tokio::spawn的定义要求其产生的未来结果实现Send特性。是否必须修改ResultSet结构才能实现Send?有更好的方法吗?

pub fn query_named(
&self,
sql: &str,
params: &[(&str, &dyn ToSql)],
) -> Result<ResultSet<Row>, Error>{
let rows = self.conn.query_named(sql, params)?;
Ok(rows)
}
pub async fn translate_result(
rm_result: Vec<sqlserver_mod2::MyResult>,
) -> Result<String, Error> {
let res_get_ryxm = ordb.query_named(sql_getRYXM, &[("barcode", &"900421757188")]).unwrap();
otherfun(res_get_ryxm);
}
spawn(async {
translate_result().await;
});

如果异步代码在LocalSet:的上下文中执行,则可以使用tokio::task::spawn_local

use std::future::Future;
use std::pin::Pin;
use tokio::task::LocalSet;
// This is explicitly a !Send future
fn f() -> Pin<Box<dyn Future<Output = ()>>> {
Box::pin(async {
println!("hey, it worked");
// can use spawn_local() here
})
}
// This creates a multi-threaded runtime
#[tokio::main]
async fn main() {
let local = LocalSet::new();
local.run_until(f()).await;
}

然而,一定要注意它的文档,因为它的使用位置有很多限制,因为它违背了tokio的阻塞和工作窃取模式。


如果这将在整个代码库中广泛使用,您可以选择使用activx-rt而不是直接使用tokio:

Actix生态系统的基于Tokio的单线程异步运行时。

在Actix生态系统的大多数部分,都选择使用!Send期货。因此,单线程运行时是合适的,因为它可以保证未来不会在线程之间移动。与需要原子的情况相比,这可能会带来较小的性能改进。

为了实现与多线程、窃取工作的运行时类似的性能,使用actix-rt的应用程序将创建多个(大部分是断开连接的(单线程运行时。对于大多数任务的运行时开销相似的工作负载,这种方法具有良好的性能特性。

最新更新