Rust Tauri应用定时Reqwest请求阻塞主代码问题求助
解决Tauri应用定时请求阻塞主程序的问题
问题根源
直接在Tauri的setup函数中使用阻塞式的loop + thread::sleep()会卡住主线程——因为setup是同步执行的,主线程被阻塞后,Tauri的事件循环无法正常运行,导致整个应用停止响应。
解决方案步骤
1. 重构set_ip异步函数
移除set_ip函数上的#[tokio::main]宏,因为Tauri已经集成了Tokio runtime,不需要再创建新的runtime实例,直接保留普通异步函数即可:
// firebase.rs 修改后代码 pub async fn set_ip(ip: std::net::IpAddr, config: &tauri::Config) { let client = Client::new(); let user = config::read(config).unwrap().user_data; let token = auth(user.email.as_str(), user.password.as_str()).await.unwrap(); let response = client .get( format!( "https://firestore.googleapis.com/v1/my_db/(default)/documents/users/{}", user.email ) ) .header("Authorization", format!("Bearer {}", token)) .header("content-type", "application/json") .send().await .unwrap() .text().await .unwrap(); let mut data: serde_json::Value = serde_json::from_str(&response).expect("ERROR parsing"); data["fields"]["ip"]["stringValue"] = serde_json::Value::String(ip.to_string()); let _post_ip = client .patch( format!( "https://firestore.googleapis.com/v1/projects/my_db/documents/users/{}", user.email ) ) .body(serde_json::to_string(&data).expect("Error stringing value")) .header("Authorization", format!("Bearer {}", token)) .header("content-type", "application/json") .send().await .unwrap(); }
2. 在setup中启动异步后台定时任务
使用Tokio的spawn将定时任务放到后台线程池执行,搭配tokio::time::Interval实现非阻塞的定时逻辑,避免阻塞主线程:
// main.rs 修改后setup代码 .setup(|app| { let config = app::storage::config::read(&app.config()).unwrap(); if config.show_window_on_start { app::window::new(app.handle()); } // 克隆配置,满足后台任务的'static生命周期要求 let cloned_config = app.config().clone(); // 启动异步后台任务 tokio::spawn(async move { // 初始化30分钟间隔的定时器 let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(30 * 60)); // 程序启动时先执行一次IP上报 let ip = server::network::get_ip(); if let Err(e) = app::api::firebase::set_ip(ip, &cloned_config).await { eprintln!("IP上报失败: {}", e); } // 进入定时循环 loop { // 等待下一个时间点(非阻塞) interval.tick().await; let ip = server::network::get_ip(); if let Err(e) = app::api::firebase::set_ip(ip, &cloned_config).await { eprintln!("IP上报失败: {}", e); } } }); Ok(()) })
关键说明
tokio::spawn:将任务提交到Tokio线程池异步执行,不会阻塞主线程,保证Tauri的事件循环正常运行。tokio::time::Interval:异步定时器,比阻塞式的thread::sleep()更适合异步场景,不会占用线程资源。- 错误处理:替换原代码中的
unwrap()为if let Err,避免后台任务panic导致整个应用崩溃。
内容的提问来源于stack exchange,提问作者vstanika
相关产品推荐
相关产品推荐

